diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 000000000000..4296655a040f --- /dev/null +++ b/.clippy.toml @@ -0,0 +1 @@ +allow-dbg-in-tests = true diff --git a/.github/workflows/cypress-tests-runner.yml b/.github/workflows/cypress-tests-runner.yml index e07b4e48d6ff..bb22a5692ade 100644 --- a/.github/workflows/cypress-tests-runner.yml +++ b/.github/workflows/cypress-tests-runner.yml @@ -14,7 +14,6 @@ env: CARGO_INCREMENTAL: 0 CARGO_NET_RETRY: 10 PAYMENTS_CONNECTORS: "cybersource stripe" - PAYOUTS_CONNECTORS: "wise" RUST_BACKTRACE: short RUSTUP_MAX_RETRIES: 10 RUN_TESTS: ${{ ((github.event_name == 'pull_request') && (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name)) || (github.event_name == 'merge_group')}} @@ -22,6 +21,65 @@ env: RUST_MIN_STACK: 10485760 jobs: + formatter: + name: Run formatter on Cypress tests and address lints + if: ${{ github.event_name == 'pull_request' }} + runs-on: ubuntu-latest + steps: + - name: Generate a token + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }} + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.HYPERSWITCH_BOT_APP_ID }} + private-key: ${{ secrets.HYPERSWITCH_BOT_APP_PRIVATE_KEY }} + + - name: Checkout repository with token + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }} + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.ref }} + token: ${{ steps.generate_token.outputs.token }} + + - name: Checkout repository for fork + if: ${{ github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name }} + uses: actions/checkout@v4 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install Cypress and dependencies + run: | + npm ci --prefix ./cypress-tests + + - name: Check formatting for forked pull requests + if: ${{ github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name }} + shell: bash + run: | + npm run format:check --prefix cypress-tests + npm run lint --prefix cypress-tests + + - name: Check formatting + if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }} + shell: bash + run: | + npm run format --prefix cypress-tests + npm run lint --prefix cypress-tests -- --fix + + if ! git diff --exit-code --quiet -- cypress-tests; then + echo "::notice::Cypress formatting and lint check failed" + + git config --local user.name 'hyperswitch-bot[bot]' + git config --local user.email '148525504+hyperswitch-bot[bot]@users.noreply.github.com' + + git add cypress-tests + git commit --message 'chore(cypress): run formatter and address lints' + git push + fi + runner: name: Run Cypress tests runs-on: ubuntu-latest @@ -69,7 +127,7 @@ jobs: CONNECTOR_AUTH_PASSPHRASE: ${{ secrets.CONNECTOR_AUTH_PASSPHRASE }} CONNECTOR_CREDS_S3_BUCKET_URI: ${{ secrets.CONNECTOR_CREDS_S3_BUCKET_URI}} DESTINATION_FILE_NAME: "creds.json.gpg" - S3_SOURCE_FILE_NAME: "5a3f7679-445e-4621-86c5-39bd8d26b7c5.json.gpg" + S3_SOURCE_FILE_NAME: "6f8289a9-6da0-433b-8a24-18d4d7257b7f.json.gpg" shell: bash run: | mkdir -p ".github/secrets" ".github/test" diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f748c6924ad..928ec1ead7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,58 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.12.05.0 + +### Features + +- **themes:** Create APIs for managing themes ([#6658](https://github.com/juspay/hyperswitch/pull/6658)) ([`3a3e93c`](https://github.com/juspay/hyperswitch/commit/3a3e93cb3be3fc3ffabef2a708b49defabf338a5)) +- Add resources and granular permission groups for reconciliation ([#6591](https://github.com/juspay/hyperswitch/pull/6591)) ([`fa21ef8`](https://github.com/juspay/hyperswitch/commit/fa21ef892da1b2ff511a39134ffdcc5d404dc91a)) + +### Refactors + +- **address:** Change address to domain address in application ([#6608](https://github.com/juspay/hyperswitch/pull/6608)) ([`938b2a8`](https://github.com/juspay/hyperswitch/commit/938b2a898ea3f647d57812858c6bd4dad13972a3)) +- **connector:** Add amount conversion framework to cybersource ([#6335](https://github.com/juspay/hyperswitch/pull/6335)) ([`248be9c`](https://github.com/juspay/hyperswitch/commit/248be9c73e7d627c856e5398234ff5840c93798c)) +- **gsm:** Add `error_category` column to gsm table ([#6648](https://github.com/juspay/hyperswitch/pull/6648)) ([`fd82cf6`](https://github.com/juspay/hyperswitch/commit/fd82cf610a15143559f8db1038c8c65ede6e7b7c)) + +### Miscellaneous Tasks + +- Wasm paze additional details ([#6710](https://github.com/juspay/hyperswitch/pull/6710)) ([`35f963c`](https://github.com/juspay/hyperswitch/commit/35f963c2e8a48add26bc80e6a828e2d18e6f1058)) + +**Full Changelog:** [`2024.12.04.0...2024.12.05.0`](https://github.com/juspay/hyperswitch/compare/2024.12.04.0...2024.12.05.0) + +- - - + +## 2024.12.04.0 + +### Features + +- **cypress:** Add multiple creds and flags support ([#6588](https://github.com/juspay/hyperswitch/pull/6588)) ([`6438391`](https://github.com/juspay/hyperswitch/commit/64383915bda5693df1cecf6cc5683e8b9aaef99b)) + +**Full Changelog:** [`2024.12.03.0...2024.12.04.0`](https://github.com/juspay/hyperswitch/compare/2024.12.03.0...2024.12.04.0) + +- - - + +## 2024.12.03.0 + +### Features + +- **payment_methods_v2:** Implement a barebones version of list customer payment methods v2 ([#6649](https://github.com/juspay/hyperswitch/pull/6649)) ([`797a0db`](https://github.com/juspay/hyperswitch/commit/797a0db7733c5b387564fb1bbc106d054c8dffa6)) +- **routing:** Elimination routing switch for toggling the feature ([#6568](https://github.com/juspay/hyperswitch/pull/6568)) ([`f6dde13`](https://github.com/juspay/hyperswitch/commit/f6dde13d6c2920761f236969a3862fe61f3e0e3d)) + +### Bug Fixes + +- **connector:** Adyen - propagate connector mandate details in incoming webhooks ([#6720](https://github.com/juspay/hyperswitch/pull/6720)) ([`bea4b9e`](https://github.com/juspay/hyperswitch/commit/bea4b9e7f430c3d7fbb25be0b472d2afb01135ec)) +- **opensearch:** Fix empty filter array query addition in globalsearch query ([#6716](https://github.com/juspay/hyperswitch/pull/6716)) ([`063a1c6`](https://github.com/juspay/hyperswitch/commit/063a1c636ce29ca8f76c3c272c6da4d32d356cda)) +- **payment_link:** Add support for hide card nickname field for open payment links ([#6700](https://github.com/juspay/hyperswitch/pull/6700)) ([`933911e`](https://github.com/juspay/hyperswitch/commit/933911eda11f32d72ffeddb948b86672cb08105b)) + +### Miscellaneous Tasks + +- Address Rust 1.83.0 clippy lints and enable more clippy lints ([#6705](https://github.com/juspay/hyperswitch/pull/6705)) ([`9a59d0a`](https://github.com/juspay/hyperswitch/commit/9a59d0a5ff682cd7a983a63e90113afc846aeac6)) + +**Full Changelog:** [`2024.12.02.1...2024.12.03.0`](https://github.com/juspay/hyperswitch/compare/2024.12.02.1...2024.12.03.0) + +- - - + ## 2024.12.02.1 ### Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index 4118ea29c2da..e8315e8049a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -455,6 +455,7 @@ checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" name = "api_models" version = "0.1.0" dependencies = [ + "actix-multipart", "actix-web", "cards", "common_enums", @@ -4054,6 +4055,7 @@ dependencies = [ "reqwest 0.11.27", "ring 0.17.8", "router_env", + "roxmltree", "serde", "serde_json", "serde_urlencoded", @@ -6675,7 +6677,6 @@ dependencies = [ "ring 0.17.8", "router_derive", "router_env", - "roxmltree", "rust-i18n", "rust_decimal", "rustc-hash", diff --git a/Cargo.toml b/Cargo.toml index 90eb996b82b3..38d895d767af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,12 +18,16 @@ unused_qualifications = "warn" [workspace.lints.clippy] as_conversions = "warn" +cloned_instead_of_copied = "warn" +dbg_macro = "warn" expect_used = "warn" +fn_params_excessive_bools = "warn" index_refutable_slice = "warn" indexing_slicing = "warn" large_futures = "warn" match_on_vec_items = "warn" missing_panics_doc = "warn" +mod_module_files = "warn" out_of_bounds_indexing = "warn" panic = "warn" panic_in_result_fn = "warn" @@ -32,10 +36,12 @@ print_stderr = "warn" print_stdout = "warn" todo = "warn" unimplemented = "warn" +unnecessary_self_imports = "warn" unreachable = "warn" unwrap_in_result = "warn" unwrap_used = "warn" use_self = "warn" +wildcard_dependencies = "warn" # Lints to allow option_map_unit_fn = "allow" diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index e3f54813a43d..1af9284596d9 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -1278,7 +1278,7 @@ ], "summary": "Routing - Create", "description": "Create a routing algorithm", - "operationId": "Create a routing algprithm", + "operationId": "Create a routing algorithm", "requestBody": { "content": { "application/json": { @@ -2972,8 +2972,8 @@ "required": [ "order_amount", "currency", - "skip_external_tax_calculation", - "skip_surcharge_calculation" + "external_tax_calculation", + "surcharge_calculation" ], "properties": { "order_amount": { @@ -3002,10 +3002,10 @@ ], "nullable": true }, - "skip_external_tax_calculation": { + "external_tax_calculation": { "$ref": "#/components/schemas/TaxCalculationOverride" }, - "skip_surcharge_calculation": { + "surcharge_calculation": { "$ref": "#/components/schemas/SurchargeCalculationOverride" }, "surcharge_amount": { @@ -4176,7 +4176,7 @@ }, "bank_account_bic": { "type": "string", - "description": "Bank account details for Giropay\nBank account bic code", + "description": "Bank account bic code", "nullable": true }, "bank_account_iban": { @@ -6125,8 +6125,8 @@ "type": "object", "required": [ "currency", - "skip_external_tax_calculation", - "skip_surcharge_calculation", + "external_tax_calculation", + "surcharge_calculation", "net_amount", "amount_capturable" ], @@ -6157,10 +6157,10 @@ ], "nullable": true }, - "skip_external_tax_calculation": { + "external_tax_calculation": { "$ref": "#/components/schemas/TaxCalculationOverride" }, - "skip_surcharge_calculation": { + "surcharge_calculation": { "$ref": "#/components/schemas/SurchargeCalculationOverride" }, "surcharge_amount": { @@ -7776,6 +7776,16 @@ } } }, + "ErrorCategory": { + "type": "string", + "enum": [ + "frm_decline", + "processor_downtime", + "processor_decline_unauthorized", + "issue_with_payment_method", + "processor_decline_incorrect_data" + ] + }, "ErrorDetails": { "type": "object", "description": "Error details for the payment", @@ -9162,6 +9172,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -9295,6 +9313,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -9391,6 +9417,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -14971,6 +15005,7 @@ "status", "amount_details", "client_secret", + "profile_id", "capture_method", "authentication_type", "customer_present", @@ -14997,6 +15032,10 @@ "description": "It's a token used for client side verification.", "example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo" }, + "profile_id": { + "type": "string", + "description": "The identifier for the profile. This is inferred from the `x-profile-id` header" + }, "merchant_reference_id": { "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", @@ -15816,6 +15855,22 @@ } ], "nullable": true + }, + "shipping": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true + }, + "billing": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true } } }, @@ -19661,8 +19716,8 @@ "SurchargeCalculationOverride": { "type": "string", "enum": [ - "Skip", - "Calculate" + "skip", + "calculate" ] }, "SurchargeDetailsResponse": { @@ -19763,8 +19818,8 @@ "TaxCalculationOverride": { "type": "string", "enum": [ - "Skip", - "Calculate" + "skip", + "calculate" ] }, "ThirdPartySdkSessionResponse": { diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 25ed2648cd4a..f2904dd4783c 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -867,7 +867,6 @@ "Payments" ], "summary": "Payments - Complete Authorize", - "description": "\n", "operationId": "Complete Authorize a Payment", "parameters": [ { @@ -918,7 +917,6 @@ "Payments" ], "summary": "Payments - Post Session Tokens", - "description": "\n", "operationId": "Create Post Session Tokens for a Payment", "requestBody": { "content": { @@ -3931,7 +3929,7 @@ ], "summary": "Routing - Toggle success based dynamic routing for profile", "description": "Create a success based dynamic routing algorithm", - "operationId": "Toggle success based dynamic routing algprithm", + "operationId": "Toggle success based dynamic routing algorithm", "parameters": [ { "name": "account_id", @@ -3957,7 +3955,7 @@ "description": "Feature to enable for success based routing", "required": true, "schema": { - "$ref": "#/components/schemas/SuccessBasedRoutingFeatures" + "$ref": "#/components/schemas/DynamicRoutingFeatures" } } ], @@ -6757,7 +6755,7 @@ }, "bank_account_bic": { "type": "string", - "description": "Bank account details for Giropay\nBank account bic code", + "description": "Bank account bic code", "nullable": true }, "bank_account_iban": { @@ -10236,6 +10234,14 @@ } } }, + "DynamicRoutingFeatures": { + "type": "string", + "enum": [ + "metrics", + "dynamic_connector_selection", + "none" + ] + }, "EnabledPaymentMethod": { "type": "object", "description": "Object for EnabledPaymentMethod", @@ -10290,6 +10296,16 @@ } } }, + "ErrorCategory": { + "type": "string", + "enum": [ + "frm_decline", + "processor_downtime", + "processor_decline_unauthorized", + "issue_with_payment_method", + "processor_decline_incorrect_data" + ] + }, "EventClass": { "type": "string", "enum": [ @@ -11633,6 +11649,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -11766,6 +11790,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -11862,6 +11894,14 @@ "type": "string", "description": "error message unified across the connectors", "nullable": true + }, + "error_category": { + "allOf": [ + { + "$ref": "#/components/schemas/ErrorCategory" + } + ], + "nullable": true } } }, @@ -23874,14 +23914,6 @@ "destination" ] }, - "SuccessBasedRoutingFeatures": { - "type": "string", - "enum": [ - "metrics", - "dynamic_connector_selection", - "none" - ] - }, "SurchargeDetailsResponse": { "type": "object", "required": [ @@ -24098,6 +24130,28 @@ } } }, + "ToggleDynamicRoutingPath": { + "type": "object", + "required": [ + "profile_id" + ], + "properties": { + "profile_id": { + "type": "string" + } + } + }, + "ToggleDynamicRoutingQuery": { + "type": "object", + "required": [ + "enable" + ], + "properties": { + "enable": { + "$ref": "#/components/schemas/DynamicRoutingFeatures" + } + } + }, "ToggleKVRequest": { "type": "object", "required": [ @@ -24131,28 +24185,6 @@ } } }, - "ToggleSuccessBasedRoutingPath": { - "type": "object", - "required": [ - "profile_id" - ], - "properties": { - "profile_id": { - "type": "string" - } - } - }, - "ToggleSuccessBasedRoutingQuery": { - "type": "object", - "required": [ - "enable" - ], - "properties": { - "enable": { - "$ref": "#/components/schemas/SuccessBasedRoutingFeatures" - } - } - }, "TouchNGoRedirection": { "type": "object" }, diff --git a/config/config.example.toml b/config/config.example.toml index 03ebedf0d35e..54a3ab3827bd 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -795,3 +795,6 @@ connector_list = "stripe,adyen,cybersource" # Supported connectors for network t host = "localhost" # Client Host port = 7000 # Client Port service = "dynamo" # Service name + +[theme_storage] +file_storage_backend = "file_system" # Theme storage backend to be used diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml index fa0c0484a773..5cadc66ddfc5 100644 --- a/config/deployments/env_specific.toml +++ b/config/deployments/env_specific.toml @@ -327,3 +327,10 @@ check_token_status_url= "" # base url to check token status from token servic host = "localhost" # Client Host port = 7000 # Client Port service = "dynamo" # Service name + +[theme_storage] +file_storage_backend = "aws_s3" # Theme storage backend to be used + +[theme_storage.aws_s3] +region = "bucket_region" # AWS region where the S3 bucket for theme storage is located +bucket_name = "bucket" # AWS S3 bucket name for theme storage diff --git a/config/development.toml b/config/development.toml index d8251cfce7bf..eef44648c6c3 100644 --- a/config/development.toml +++ b/config/development.toml @@ -793,3 +793,6 @@ connector_list = "cybersource" [grpc_client.dynamic_routing_client] host = "localhost" port = 7000 + +[theme_storage] +file_storage_backend = "file_system" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 976a2fa2a42c..f38da4183b1a 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -691,3 +691,6 @@ prod_intent_recipient_email = "business@example.com" # Recipient email for prod [email.aws_ses] email_role_arn = "" # The amazon resource name ( arn ) of the role which has permission to send emails sts_role_session_name = "" # An identifier for the assumed role session, used to uniquely identify a session. + +[theme_storage] +file_storage_backend = "file_system" # Theme storage backend to be used diff --git a/crates/analytics/src/disputes/metrics/sessionized_metrics/mod.rs b/crates/analytics/src/disputes/metrics/sessionized_metrics.rs similarity index 100% rename from crates/analytics/src/disputes/metrics/sessionized_metrics/mod.rs rename to crates/analytics/src/disputes/metrics/sessionized_metrics.rs diff --git a/crates/analytics/src/opensearch.rs b/crates/analytics/src/opensearch.rs index e8726840a2ea..246a0f4e8bb3 100644 --- a/crates/analytics/src/opensearch.rs +++ b/crates/analytics/src/opensearch.rs @@ -705,9 +705,7 @@ impl OpenSearchQueryBuilder { let should_array = self.build_auth_array(); - if !bool_obj.is_empty() { - query_obj.insert("bool".to_string(), Value::Object(bool_obj)); - } + query_obj.insert("bool".to_string(), Value::Object(bool_obj)); let mut sort_obj = Map::new(); sort_obj.insert( diff --git a/crates/analytics/src/payment_intents/metrics/sessionized_metrics/mod.rs b/crates/analytics/src/payment_intents/metrics/sessionized_metrics.rs similarity index 100% rename from crates/analytics/src/payment_intents/metrics/sessionized_metrics/mod.rs rename to crates/analytics/src/payment_intents/metrics/sessionized_metrics.rs diff --git a/crates/analytics/src/payments/metrics/sessionized_metrics/mod.rs b/crates/analytics/src/payments/metrics/sessionized_metrics.rs similarity index 100% rename from crates/analytics/src/payments/metrics/sessionized_metrics/mod.rs rename to crates/analytics/src/payments/metrics/sessionized_metrics.rs diff --git a/crates/analytics/src/refunds/metrics/sessionized_metrics/mod.rs b/crates/analytics/src/refunds/metrics/sessionized_metrics.rs similarity index 100% rename from crates/analytics/src/refunds/metrics/sessionized_metrics/mod.rs rename to crates/analytics/src/refunds/metrics/sessionized_metrics.rs diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml index a5d702e26fb1..eb706dc913c0 100644 --- a/crates/api_models/Cargo.toml +++ b/crates/api_models/Cargo.toml @@ -8,7 +8,7 @@ readme = "README.md" license.workspace = true [features] -errors = ["dep:actix-web", "dep:reqwest"] +errors = ["dep:reqwest"] dummy_connector = ["euclid/dummy_connector", "common_enums/dummy_connector"] detailed_errors = [] payouts = ["common_enums/payouts"] @@ -23,7 +23,8 @@ payment_methods_v2 = ["common_utils/payment_methods_v2"] dynamic_routing = [] [dependencies] -actix-web = { version = "4.5.1", optional = true } +actix-multipart = "0.6.1" +actix-web = "4.5.1" error-stack = "0.4.1" indexmap = "2.3.0" mime = "0.3.17" diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 7e1465c9d929..f0a8c9994382 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -1531,7 +1531,6 @@ pub struct MerchantConnectorUpdate { #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(deny_unknown_fields)] - pub struct ConnectorWalletDetails { /// This field contains the Apple Pay certificates and credentials for iOS and Web Apple Pay flow #[serde(skip_serializing_if = "Option::is_none")] diff --git a/crates/api_models/src/analytics.rs b/crates/api_models/src/analytics.rs index d25f35589b67..b6d4044c5f3c 100644 --- a/crates/api_models/src/analytics.rs +++ b/crates/api_models/src/analytics.rs @@ -277,7 +277,6 @@ pub struct PaymentIntentFilterValue { #[derive(Debug, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "camelCase")] - pub struct GetRefundFilterRequest { pub time_range: TimeRange, #[serde(default)] @@ -292,7 +291,6 @@ pub struct RefundFiltersResponse { #[derive(Debug, serde::Serialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] - pub struct RefundFilterValue { pub dimension: RefundDimensions, pub values: Vec, @@ -435,7 +433,6 @@ pub struct DisputeFiltersResponse { #[derive(Debug, serde::Serialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] - pub struct DisputeFilterValue { pub dimension: DisputeDimensions, pub values: Vec, diff --git a/crates/api_models/src/api_keys.rs b/crates/api_models/src/api_keys.rs index d25cd989b0f0..3c4d566f2354 100644 --- a/crates/api_models/src/api_keys.rs +++ b/crates/api_models/src/api_keys.rs @@ -212,7 +212,7 @@ mod never { { struct NeverVisitor; - impl<'de> serde::de::Visitor<'de> for NeverVisitor { + impl serde::de::Visitor<'_> for NeverVisitor { type Value = (); fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/crates/api_models/src/conditional_configs.rs b/crates/api_models/src/conditional_configs.rs index 555e7bd955f0..3aed34e47a76 100644 --- a/crates/api_models/src/conditional_configs.rs +++ b/crates/api_models/src/conditional_configs.rs @@ -92,7 +92,6 @@ pub struct ConditionalConfigReq { pub algorithm: Option>, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] - pub struct DecisionManagerRequest { pub name: Option, pub program: Option>, diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 646ad122d7c9..4af3f855d77b 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -141,7 +141,6 @@ pub enum FrmConnectors { )] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] - pub enum TaxConnectors { Taxjar, } @@ -447,3 +446,20 @@ pub enum StripeChargeType { pub fn convert_frm_connector(connector_name: &str) -> Option { FrmConnectors::from_str(connector_name).ok() } + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, Hash)] +pub enum ReconPermissionScope { + #[serde(rename = "R")] + Read = 0, + #[serde(rename = "RW")] + Write = 1, +} + +impl From for ReconPermissionScope { + fn from(scope: PermissionScope) -> Self { + match scope { + PermissionScope::Read => Self::Read, + PermissionScope::Write => Self::Write, + } + } +} diff --git a/crates/api_models/src/errors/mod.rs b/crates/api_models/src/errors.rs similarity index 100% rename from crates/api_models/src/errors/mod.rs rename to crates/api_models/src/errors.rs diff --git a/crates/api_models/src/events/recon.rs b/crates/api_models/src/events/recon.rs index aed648f4c869..596b05412827 100644 --- a/crates/api_models/src/events/recon.rs +++ b/crates/api_models/src/events/recon.rs @@ -1,6 +1,9 @@ use common_utils::events::{ApiEventMetric, ApiEventsType}; +use masking::PeekInterface; -use crate::recon::{ReconStatusResponse, ReconTokenResponse, ReconUpdateMerchantRequest}; +use crate::recon::{ + ReconStatusResponse, ReconTokenResponse, ReconUpdateMerchantRequest, VerifyTokenResponse, +}; impl ApiEventMetric for ReconUpdateMerchantRequest { fn get_api_event_type(&self) -> Option { @@ -19,3 +22,11 @@ impl ApiEventMetric for ReconStatusResponse { Some(ApiEventsType::Recon) } } + +impl ApiEventMetric for VerifyTokenResponse { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::User { + user_id: self.user_email.peek().to_string(), + }) + } +} diff --git a/crates/api_models/src/events/routing.rs b/crates/api_models/src/events/routing.rs index ffa5e008f0a5..87e7fa278859 100644 --- a/crates/api_models/src/events/routing.rs +++ b/crates/api_models/src/events/routing.rs @@ -6,7 +6,7 @@ use crate::routing::{ RoutingLinkWrapper, RoutingPayloadWrapper, RoutingRetrieveLinkQuery, RoutingRetrieveLinkQueryWrapper, RoutingRetrieveQuery, SuccessBasedRoutingConfig, SuccessBasedRoutingPayloadWrapper, SuccessBasedRoutingUpdateConfigQuery, - ToggleSuccessBasedRoutingQuery, ToggleSuccessBasedRoutingWrapper, + ToggleDynamicRoutingQuery, ToggleDynamicRoutingWrapper, }; impl ApiEventMetric for RoutingKind { @@ -79,7 +79,7 @@ impl ApiEventMetric for RoutingRetrieveLinkQueryWrapper { } } -impl ApiEventMetric for ToggleSuccessBasedRoutingQuery { +impl ApiEventMetric for ToggleDynamicRoutingQuery { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::Routing) } @@ -97,7 +97,7 @@ impl ApiEventMetric for SuccessBasedRoutingPayloadWrapper { } } -impl ApiEventMetric for ToggleSuccessBasedRoutingWrapper { +impl ApiEventMetric for ToggleDynamicRoutingWrapper { fn get_api_event_type(&self) -> Option { Some(ApiEventsType::Routing) } diff --git a/crates/api_models/src/events/user.rs b/crates/api_models/src/events/user.rs index 4dc2a1a301a6..15146e304af7 100644 --- a/crates/api_models/src/events/user.rs +++ b/crates/api_models/src/events/user.rs @@ -1,15 +1,12 @@ use common_utils::events::{ApiEventMetric, ApiEventsType}; -#[cfg(feature = "recon")] -use masking::PeekInterface; #[cfg(feature = "dummy_connector")] use crate::user::sample_data::SampleDataRequest; -#[cfg(feature = "recon")] -use crate::user::VerifyTokenResponse; use crate::user::{ dashboard_metadata::{ GetMetaDataRequest, GetMetaDataResponse, GetMultipleMetaDataPayload, SetMetaDataRequest, }, + theme::{CreateThemeRequest, GetThemeResponse, UpdateThemeRequest, UploadFileRequest}, AcceptInviteFromEmailRequest, AuthSelectRequest, AuthorizeResponse, BeginTotpResponse, ChangePasswordRequest, ConnectAccountRequest, CreateInternalUserRequest, CreateUserAuthenticationMethodRequest, ForgotPasswordRequest, GetSsoAuthUrlRequest, @@ -23,15 +20,6 @@ use crate::user::{ VerifyTotpRequest, }; -#[cfg(feature = "recon")] -impl ApiEventMetric for VerifyTokenResponse { - fn get_api_event_type(&self) -> Option { - Some(ApiEventsType::User { - user_id: self.user_email.peek().to_string(), - }) - } -} - common_utils::impl_api_event_type!( Miscellaneous, ( @@ -74,7 +62,11 @@ common_utils::impl_api_event_type!( UpdateUserAuthenticationMethodRequest, GetSsoAuthUrlRequest, SsoSignInRequest, - AuthSelectRequest + AuthSelectRequest, + GetThemeResponse, + UploadFileRequest, + CreateThemeRequest, + UpdateThemeRequest ) ); diff --git a/crates/api_models/src/gsm.rs b/crates/api_models/src/gsm.rs index 30e49062439f..b95794ef707b 100644 --- a/crates/api_models/src/gsm.rs +++ b/crates/api_models/src/gsm.rs @@ -1,3 +1,4 @@ +use common_enums::ErrorCategory; use utoipa::ToSchema; use crate::enums::Connector; @@ -26,6 +27,8 @@ pub struct GsmCreateRequest { pub unified_code: Option, /// error message unified across the connectors pub unified_message: Option, + /// category in which error belongs to + pub error_category: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -88,6 +91,8 @@ pub struct GsmUpdateRequest { pub unified_code: Option, /// error message unified across the connectors pub unified_message: Option, + /// category in which error belongs to + pub error_category: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -141,4 +146,6 @@ pub struct GsmResponse { pub unified_code: Option, /// error message unified across the connectors pub unified_message: Option, + /// category in which error belongs to + pub error_category: Option, } diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index fb60937e9b13..603c0f769347 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -316,6 +316,10 @@ pub struct PaymentsIntentResponse { #[schema(value_type = String, example = "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo")] pub client_secret: common_utils::types::ClientSecret, + /// The identifier for the profile. This is inferred from the `x-profile-id` header + #[schema(value_type = String)] + pub profile_id: id_type::ProfileId, + /// Unique identifier for the payment. This ensures idempotency for multiple payments /// that have been done by a single merchant. #[schema( @@ -476,10 +480,10 @@ pub struct AmountDetailsResponse { pub order_tax_amount: Option, /// The action to whether calculate tax by calling external tax provider or not #[schema(value_type = TaxCalculationOverride)] - pub skip_external_tax_calculation: common_enums::TaxCalculationOverride, + pub external_tax_calculation: common_enums::TaxCalculationOverride, /// The action to whether calculate surcharge or not #[schema(value_type = SurchargeCalculationOverride)] - pub skip_surcharge_calculation: common_enums::SurchargeCalculationOverride, + pub surcharge_calculation: common_enums::SurchargeCalculationOverride, /// The surcharge amount to be added to the order, collected from the merchant pub surcharge_amount: Option, /// tax on surcharge amount @@ -502,10 +506,10 @@ pub struct ConfirmIntentAmountDetailsResponse { pub order_tax_amount: Option, /// The action to whether calculate tax by calling external tax provider or not #[schema(value_type = TaxCalculationOverride)] - pub skip_external_tax_calculation: common_enums::TaxCalculationOverride, + pub external_tax_calculation: common_enums::TaxCalculationOverride, /// The action to whether calculate surcharge or not #[schema(value_type = SurchargeCalculationOverride)] - pub skip_surcharge_calculation: common_enums::SurchargeCalculationOverride, + pub surcharge_calculation: common_enums::SurchargeCalculationOverride, /// The surcharge amount to be added to the order, collected from the merchant pub surcharge_amount: Option, /// tax on surcharge amount @@ -2457,7 +2461,6 @@ pub enum AdditionalPaymentData { } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] - pub struct KlarnaSdkPaymentMethod { pub payment_type: Option, } @@ -2504,7 +2507,6 @@ pub enum BankRedirectData { Giropay { /// The billing details for bank redirection billing_details: Option, - /// Bank account details for Giropay #[schema(value_type = Option)] /// Bank account bic code @@ -3682,7 +3684,6 @@ pub enum WalletResponseData { } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] - pub struct KlarnaSdkPaymentMethodResponse { pub payment_type: Option, } @@ -4196,7 +4197,6 @@ pub struct ReceiverDetails { #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema, router_derive::PolymorphicSchema)] #[generate_schemas(PaymentsCreateResponseOpenApi)] - pub struct PaymentsResponse { /// Unique identifier for the payment. This ensures idempotency for multiple payments /// that have been done by a single merchant. @@ -4733,6 +4733,12 @@ pub struct PaymentsRetrieveResponse { /// Error details for the payment if any pub error: Option, + + /// The shipping address associated with the payment intent + pub shipping: Option
, + + /// The billing address associated with the payment intent + pub billing: Option
, } #[derive(Debug, serde::Deserialize, serde::Serialize, Clone)] @@ -6355,7 +6361,7 @@ mod payment_id_type { struct PaymentIdVisitor; struct OptionalPaymentIdVisitor; - impl<'de> Visitor<'de> for PaymentIdVisitor { + impl Visitor<'_> for PaymentIdVisitor { type Value = PaymentIdType; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -6433,7 +6439,7 @@ mod payment_id_type { struct PaymentIdVisitor; struct OptionalPaymentIdVisitor; - impl<'de> Visitor<'de> for PaymentIdVisitor { + impl Visitor<'_> for PaymentIdVisitor { type Value = PaymentIdType; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -6507,7 +6513,7 @@ pub mod amount { // This is defined to provide guarded deserialization of amount // which itself handles zero and non-zero values internally - impl<'de> de::Visitor<'de> for AmountVisitor { + impl de::Visitor<'_> for AmountVisitor { type Value = Amount; fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -6707,7 +6713,6 @@ pub struct PaymentLinkStatusDetails { #[derive(Clone, Debug, serde::Deserialize, ToSchema, serde::Serialize)] #[serde(deny_unknown_fields)] - pub struct PaymentLinkListConstraints { /// limit on the number of objects to return pub limit: Option, diff --git a/crates/api_models/src/pm_auth.rs b/crates/api_models/src/pm_auth.rs index 8ed52907da8f..e97efcf92d3d 100644 --- a/crates/api_models/src/pm_auth.rs +++ b/crates/api_models/src/pm_auth.rs @@ -22,7 +22,6 @@ pub struct LinkTokenCreateResponse { #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] #[serde(rename_all = "snake_case")] - pub struct ExchangeTokenCreateRequest { pub public_token: String, pub client_secret: Option, diff --git a/crates/api_models/src/recon.rs b/crates/api_models/src/recon.rs index afee0fb5626a..f73bcc5ae1f1 100644 --- a/crates/api_models/src/recon.rs +++ b/crates/api_models/src/recon.rs @@ -1,4 +1,4 @@ -use common_utils::pii; +use common_utils::{id_type, pii}; use masking::Secret; use crate::enums; @@ -18,3 +18,11 @@ pub struct ReconTokenResponse { pub struct ReconStatusResponse { pub recon_status: enums::ReconStatus, } + +#[derive(serde::Serialize, Debug)] +pub struct VerifyTokenResponse { + pub merchant_id: id_type::MerchantId, + pub user_email: pii::Email, + #[serde(skip_serializing_if = "Option::is_none")] + pub acl: Option, +} diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs index 389af3dab7bf..6cd5d5251a31 100644 --- a/crates/api_models/src/routing.rs +++ b/crates/api_models/src/routing.rs @@ -473,7 +473,6 @@ impl RoutingAlgorithmRef { } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] - pub struct RoutingDictionaryRecord { #[schema(value_type = String)] pub id: common_utils::id_type::RoutingId, @@ -523,6 +522,92 @@ pub struct DynamicAlgorithmWithTimestamp { #[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)] pub struct DynamicRoutingAlgorithmRef { pub success_based_algorithm: Option, + pub elimination_routing_algorithm: Option, +} + +pub trait DynamicRoutingAlgoAccessor { + fn get_algorithm_id_with_timestamp( + self, + ) -> DynamicAlgorithmWithTimestamp; + fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures; +} + +impl DynamicRoutingAlgoAccessor for SuccessBasedAlgorithm { + fn get_algorithm_id_with_timestamp( + self, + ) -> DynamicAlgorithmWithTimestamp { + self.algorithm_id_with_timestamp + } + fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures { + &mut self.enabled_feature + } +} + +impl DynamicRoutingAlgoAccessor for EliminationRoutingAlgorithm { + fn get_algorithm_id_with_timestamp( + self, + ) -> DynamicAlgorithmWithTimestamp { + self.algorithm_id_with_timestamp + } + fn get_enabled_features(&mut self) -> &mut DynamicRoutingFeatures { + &mut self.enabled_feature + } +} + +impl EliminationRoutingAlgorithm { + pub fn new( + algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp< + common_utils::id_type::RoutingId, + >, + ) -> Self { + Self { + algorithm_id_with_timestamp, + enabled_feature: DynamicRoutingFeatures::None, + } + } +} + +impl SuccessBasedAlgorithm { + pub fn new( + algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp< + common_utils::id_type::RoutingId, + >, + ) -> Self { + Self { + algorithm_id_with_timestamp, + enabled_feature: DynamicRoutingFeatures::None, + } + } +} + +impl DynamicRoutingAlgorithmRef { + pub fn update(&mut self, new: Self) { + if let Some(elimination_routing_algorithm) = new.elimination_routing_algorithm { + self.elimination_routing_algorithm = Some(elimination_routing_algorithm) + } + if let Some(success_based_algorithm) = new.success_based_algorithm { + self.success_based_algorithm = Some(success_based_algorithm) + } + } + + pub fn update_specific_ref( + &mut self, + algo_type: DynamicRoutingType, + feature_to_enable: DynamicRoutingFeatures, + ) { + match algo_type { + DynamicRoutingType::SuccessRateBasedRouting => { + self.success_based_algorithm + .as_mut() + .map(|algo| algo.enabled_feature = feature_to_enable); + } + DynamicRoutingType::EliminationRouting => { + self.elimination_routing_algorithm + .as_mut() + .map(|algo| algo.enabled_feature = feature_to_enable); + } + } + } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] @@ -530,11 +615,25 @@ pub struct SuccessBasedAlgorithm { pub algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp, #[serde(default)] - pub enabled_feature: SuccessBasedRoutingFeatures, + pub enabled_feature: DynamicRoutingFeatures, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct EliminationRoutingAlgorithm { + pub algorithm_id_with_timestamp: + DynamicAlgorithmWithTimestamp, + #[serde(default)] + pub enabled_feature: DynamicRoutingFeatures, +} + +impl EliminationRoutingAlgorithm { + pub fn update_enabled_features(&mut self, feature_to_enable: DynamicRoutingFeatures) { + self.enabled_feature = feature_to_enable + } } impl SuccessBasedAlgorithm { - pub fn update_enabled_features(&mut self, feature_to_enable: SuccessBasedRoutingFeatures) { + pub fn update_enabled_features(&mut self, feature_to_enable: DynamicRoutingFeatures) { self.enabled_feature = feature_to_enable } } @@ -543,26 +642,40 @@ impl DynamicRoutingAlgorithmRef { pub fn update_algorithm_id( &mut self, new_id: common_utils::id_type::RoutingId, - enabled_feature: SuccessBasedRoutingFeatures, + enabled_feature: DynamicRoutingFeatures, + dynamic_routing_type: DynamicRoutingType, ) { - self.success_based_algorithm = Some(SuccessBasedAlgorithm { - algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp { - algorithm_id: Some(new_id), - timestamp: common_utils::date_time::now_unix_timestamp(), - }, - enabled_feature, - }) + match dynamic_routing_type { + DynamicRoutingType::SuccessRateBasedRouting => { + self.success_based_algorithm = Some(SuccessBasedAlgorithm { + algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp { + algorithm_id: Some(new_id), + timestamp: common_utils::date_time::now_unix_timestamp(), + }, + enabled_feature, + }) + } + DynamicRoutingType::EliminationRouting => { + self.elimination_routing_algorithm = Some(EliminationRoutingAlgorithm { + algorithm_id_with_timestamp: DynamicAlgorithmWithTimestamp { + algorithm_id: Some(new_id), + timestamp: common_utils::date_time::now_unix_timestamp(), + }, + enabled_feature, + }) + } + }; } } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] -pub struct ToggleSuccessBasedRoutingQuery { - pub enable: SuccessBasedRoutingFeatures, +pub struct ToggleDynamicRoutingQuery { + pub enable: DynamicRoutingFeatures, } #[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, ToSchema)] #[serde(rename_all = "snake_case")] -pub enum SuccessBasedRoutingFeatures { +pub enum DynamicRoutingFeatures { Metrics, DynamicConnectorSelection, #[default] @@ -578,26 +691,52 @@ pub struct SuccessBasedRoutingUpdateConfigQuery { } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] -pub struct ToggleSuccessBasedRoutingWrapper { +pub struct ToggleDynamicRoutingWrapper { pub profile_id: common_utils::id_type::ProfileId, - pub feature_to_enable: SuccessBasedRoutingFeatures, + pub feature_to_enable: DynamicRoutingFeatures, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] -pub struct ToggleSuccessBasedRoutingPath { +pub struct ToggleDynamicRoutingPath { #[schema(value_type = String)] pub profile_id: common_utils::id_type::ProfileId, } + +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)] +pub struct EliminationRoutingConfig { + pub params: Option>, + // pub labels: Option>, + pub elimination_analyser_config: Option, +} + +#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)] +pub struct EliminationAnalyserConfig { + pub bucket_size: Option, + pub bucket_ttl_in_mins: Option, +} + +impl Default for EliminationRoutingConfig { + fn default() -> Self { + Self { + params: Some(vec![DynamicRoutingConfigParams::PaymentMethod]), + elimination_analyser_config: Some(EliminationAnalyserConfig { + bucket_size: Some(5), + bucket_ttl_in_mins: Some(2.0), + }), + } + } +} + #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema)] pub struct SuccessBasedRoutingConfig { - pub params: Option>, + pub params: Option>, pub config: Option, } impl Default for SuccessBasedRoutingConfig { fn default() -> Self { Self { - params: Some(vec![SuccessBasedRoutingConfigParams::PaymentMethod]), + params: Some(vec![DynamicRoutingConfigParams::PaymentMethod]), config: Some(SuccessBasedRoutingConfigBody { min_aggregates_size: Some(2), default_success_rate: Some(100.0), @@ -612,7 +751,7 @@ impl Default for SuccessBasedRoutingConfig { } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, ToSchema, strum::Display)] -pub enum SuccessBasedRoutingConfigParams { +pub enum DynamicRoutingConfigParams { PaymentMethod, PaymentMethodType, AuthenticationType, @@ -643,6 +782,12 @@ pub struct SuccessBasedRoutingPayloadWrapper { pub profile_id: common_utils::id_type::ProfileId, } +#[derive(Debug, Clone, strum::Display, serde::Serialize, serde::Deserialize)] +pub enum DynamicRoutingType { + SuccessRateBasedRouting, + EliminationRouting, +} + impl SuccessBasedRoutingConfig { pub fn update(&mut self, new: Self) { if let Some(params) = new.params { diff --git a/crates/api_models/src/user.rs b/crates/api_models/src/user.rs index 089426c68ba6..82291ddc92ac 100644 --- a/crates/api_models/src/user.rs +++ b/crates/api_models/src/user.rs @@ -8,6 +8,7 @@ use crate::user_role::UserStatus; pub mod dashboard_metadata; #[cfg(feature = "dummy_connector")] pub mod sample_data; +pub mod theme; #[derive(serde::Deserialize, Debug, Clone, serde::Serialize)] pub struct SignUpWithMerchantIdRequest { @@ -167,13 +168,6 @@ pub struct SendVerifyEmailRequest { pub email: pii::Email, } -#[cfg(feature = "recon")] -#[derive(serde::Serialize, Debug)] -pub struct VerifyTokenResponse { - pub merchant_id: id_type::MerchantId, - pub user_email: pii::Email, -} - #[derive(Debug, serde::Deserialize, serde::Serialize)] pub struct UpdateUserAccountDetailsRequest { pub name: Option>, diff --git a/crates/api_models/src/user/sample_data.rs b/crates/api_models/src/user/sample_data.rs index dc95de913faf..bfcbcb046c53 100644 --- a/crates/api_models/src/user/sample_data.rs +++ b/crates/api_models/src/user/sample_data.rs @@ -1,5 +1,4 @@ use common_enums::{AuthenticationType, CountryAlpha2}; -use common_utils::{self}; use time::PrimitiveDateTime; use crate::enums::Connector; diff --git a/crates/api_models/src/user/theme.rs b/crates/api_models/src/user/theme.rs new file mode 100644 index 000000000000..23218c4a1633 --- /dev/null +++ b/crates/api_models/src/user/theme.rs @@ -0,0 +1,125 @@ +use actix_multipart::form::{bytes::Bytes, text::Text, MultipartForm}; +use common_enums::EntityType; +use common_utils::{id_type, types::theme::ThemeLineage}; +use masking::Secret; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize)] +pub struct GetThemeResponse { + pub theme_id: String, + pub theme_name: String, + pub entity_type: EntityType, + pub tenant_id: id_type::TenantId, + pub org_id: Option, + pub merchant_id: Option, + pub profile_id: Option, + pub theme_data: ThemeData, +} + +#[derive(Debug, MultipartForm)] +pub struct UploadFileAssetData { + pub asset_name: Text, + #[multipart(limit = "10MB")] + pub asset_data: Bytes, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct UploadFileRequest { + pub lineage: ThemeLineage, + pub asset_name: String, + pub asset_data: Secret>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct CreateThemeRequest { + pub lineage: ThemeLineage, + pub theme_name: String, + pub theme_data: ThemeData, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct UpdateThemeRequest { + pub lineage: ThemeLineage, + pub theme_data: ThemeData, +} + +// All the below structs are for the theme.json file, +// which will be used by frontend to style the dashboard. +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ThemeData { + settings: Settings, + urls: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Settings { + colors: Colors, + typography: Option, + buttons: Buttons, + borders: Option, + spacing: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Colors { + primary: String, + sidebar: String, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Typography { + font_family: Option, + font_size: Option, + heading_font_size: Option, + text_color: Option, + link_color: Option, + link_hover_color: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Buttons { + primary: PrimaryButton, + secondary: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct PrimaryButton { + background_color: Option, + text_color: Option, + hover_background_color: String, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct SecondaryButton { + background_color: Option, + text_color: Option, + hover_background_color: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Borders { + default_radius: Option, + border_color: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Spacing { + padding: Option, + margin: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +struct Urls { + favicon_url: Option, + logo_url: Option, +} diff --git a/crates/cards/src/validate.rs b/crates/cards/src/validate.rs index d3515ef02f0d..d3a27da4823b 100644 --- a/crates/cards/src/validate.rs +++ b/crates/cards/src/validate.rs @@ -10,14 +10,10 @@ use router_env::{logger, which as router_env_which, Env}; use serde::{Deserialize, Deserializer, Serialize}; use thiserror::Error; -/// /// Minimum limit of a card number will not be less than 8 by ISO standards -/// pub const MIN_CARD_NUMBER_LENGTH: usize = 8; -/// /// Maximum limit of a card number will not exceed 19 by ISO standards -/// pub const MAX_CARD_NUMBER_LENGTH: usize = 19; #[derive(Debug, Deserialize, Serialize, Error)] @@ -138,11 +134,9 @@ pub fn sanitize_card_number(card_number: &str) -> Result Result, CardNumberValidationErr> { let data = number.chars().try_fold( Vec::with_capacity(MAX_CARD_NUMBER_LENGTH), diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 781b5e3710a7..d966902af89b 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -2819,9 +2819,15 @@ pub enum PermissionGroup { MerchantDetailsManage, // TODO: To be deprecated, make sure DB is migrated before removing OrganizationManage, - ReconOps, AccountView, AccountManage, + ReconReportsView, + ReconReportsManage, + ReconOpsView, + // Alias is added for backward compatibility with database + // TODO: Remove alias post migration + #[serde(alias = "recon_ops")] + ReconOpsManage, } #[derive(Clone, Debug, serde::Serialize, PartialEq, Eq, Hash, strum::EnumIter)] @@ -2831,7 +2837,8 @@ pub enum ParentGroup { Workflows, Analytics, Users, - Recon, + ReconOps, + ReconReports, Account, } @@ -2854,7 +2861,13 @@ pub enum Resource { WebhookEvent, Payout, Report, - Recon, + ReconToken, + ReconFiles, + ReconAndSettlementAnalytics, + ReconUpload, + ReconReports, + RunRecon, + ReconConfig, } #[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, Hash)] @@ -3328,6 +3341,7 @@ pub enum PresenceOfCustomerDuringPayment { } #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema)] +#[serde(rename_all = "snake_case")] pub enum TaxCalculationOverride { /// Skip calling the external tax provider #[default] @@ -3337,6 +3351,7 @@ pub enum TaxCalculationOverride { } #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, Default, ToSchema)] +#[serde(rename_all = "snake_case")] pub enum SurchargeCalculationOverride { /// Skip calculating surcharge #[default] @@ -3357,3 +3372,28 @@ pub enum ConnectorMandateStatus { /// Indicates that the connector mandate is not active and hence cannot be used for payments. Inactive, } + +#[derive( + Clone, + Copy, + Debug, + strum::Display, + PartialEq, + Eq, + serde::Serialize, + serde::Deserialize, + strum::EnumString, + ToSchema, + PartialOrd, + Ord, +)] +#[router_derive::diesel_enum(storage_type = "text")] +#[serde(rename_all = "snake_case")] +#[strum(serialize_all = "snake_case")] +pub enum ErrorCategory { + FrmDecline, + ProcessorDowntime, + ProcessorDeclineUnauthorized, + IssueWithPaymentMethod, + ProcessorDeclineIncorrectData, +} diff --git a/crates/common_enums/src/transformers.rs b/crates/common_enums/src/transformers.rs index f5f7ba3decd8..ddf55d293719 100644 --- a/crates/common_enums/src/transformers.rs +++ b/crates/common_enums/src/transformers.rs @@ -1914,7 +1914,7 @@ mod custom_serde { struct FieldVisitor; - impl<'de> Visitor<'de> for FieldVisitor { + impl Visitor<'_> for FieldVisitor { type Value = CountryAlpha2; fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { @@ -1946,7 +1946,7 @@ mod custom_serde { struct FieldVisitor; - impl<'de> Visitor<'de> for FieldVisitor { + impl Visitor<'_> for FieldVisitor { type Value = CountryAlpha3; fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { @@ -1978,7 +1978,7 @@ mod custom_serde { struct FieldVisitor; - impl<'de> Visitor<'de> for FieldVisitor { + impl Visitor<'_> for FieldVisitor { type Value = u32; fn expecting(&self, formatter: &mut Formatter<'_>) -> fmt::Result { diff --git a/crates/common_utils/src/crypto.rs b/crates/common_utils/src/crypto.rs index c7f1c286c595..e8c2b2d5a0bf 100644 --- a/crates/common_utils/src/crypto.rs +++ b/crates/common_utils/src/crypto.rs @@ -238,7 +238,6 @@ impl VerifySignature for HmacSha512 { } } -/// /// Blake3 #[derive(Debug)] pub struct Blake3(String); @@ -437,9 +436,7 @@ pub fn generate_cryptographically_secure_random_bytes() -> [u8; bytes } -/// /// A wrapper type to store the encrypted data for sensitive pii domain data types -/// #[derive(Debug, Clone)] pub struct Encryptable { inner: T, @@ -447,9 +444,7 @@ pub struct Encryptable { } impl> Encryptable> { - /// /// constructor function to be used by the encryptor and decryptor to generate the data type - /// pub fn new( masked_data: Secret, encrypted_data: Secret, EncryptionStrategy>, @@ -462,33 +457,25 @@ impl> Encryptable> { } impl Encryptable { - /// /// Get the inner data while consuming self - /// #[inline] pub fn into_inner(self) -> T { self.inner } - /// /// Get the reference to inner value - /// #[inline] pub fn get_inner(&self) -> &T { &self.inner } - /// /// Get the inner encrypted data while consuming self - /// #[inline] pub fn into_encrypted(self) -> Secret, EncryptionStrategy> { self.encrypted } - /// /// Deserialize inner value and return new Encryptable object - /// pub fn deserialize_inner_value( self, f: F, diff --git a/crates/common_utils/src/custom_serde.rs b/crates/common_utils/src/custom_serde.rs index 79e0c5b85e76..63ef30011f77 100644 --- a/crates/common_utils/src/custom_serde.rs +++ b/crates/common_utils/src/custom_serde.rs @@ -202,7 +202,6 @@ pub mod timestamp { } /// - pub mod json_string { use serde::de::{self, Deserialize, DeserializeOwned, Deserializer}; use serde_json; diff --git a/crates/common_utils/src/errors.rs b/crates/common_utils/src/errors.rs index 38b89cbfaf7e..e62606b45859 100644 --- a/crates/common_utils/src/errors.rs +++ b/crates/common_utils/src/errors.rs @@ -7,7 +7,6 @@ use crate::types::MinorUnit; /// error_stack::Report specific extendability /// /// Effectively, equivalent to `Result>` -/// pub type CustomResult = error_stack::Result; /// Parsing Errors diff --git a/crates/common_utils/src/ext_traits.rs b/crates/common_utils/src/ext_traits.rs index 5ad53ec85335..945056aafefd 100644 --- a/crates/common_utils/src/ext_traits.rs +++ b/crates/common_utils/src/ext_traits.rs @@ -1,7 +1,5 @@ -//! //! This module holds traits for extending functionalities for existing datatypes //! & inbuilt datatypes. -//! use error_stack::ResultExt; use masking::{ExposeInterface, PeekInterface, Secret, Strategy}; @@ -14,10 +12,8 @@ use crate::{ fp_utils::when, }; -/// /// Encode interface /// An interface for performing type conversions and serialization -/// pub trait Encode<'e> where Self: 'e + std::fmt::Debug, @@ -27,62 +23,49 @@ where /// Converting `Self` into an intermediate representation `

` /// and then performing encoding operation using the `Serialize` trait from `serde` /// Specifically to convert into json, by using `serde_json` - /// fn convert_and_encode

(&'e self) -> CustomResult where P: TryFrom<&'e Self> + Serialize, Result>::Error>: ResultExt, >::Error> as ResultExt>::Ok: Serialize; - /// /// Converting `Self` into an intermediate representation `

` /// and then performing encoding operation using the `Serialize` trait from `serde` /// Specifically, to convert into urlencoded, by using `serde_urlencoded` - /// fn convert_and_url_encode

(&'e self) -> CustomResult where P: TryFrom<&'e Self> + Serialize, Result>::Error>: ResultExt, >::Error> as ResultExt>::Ok: Serialize; - /// /// Functionality, for specifically encoding `Self` into `String` /// after serialization by using `serde::Serialize` - /// fn url_encode(&'e self) -> CustomResult where Self: Serialize; - /// /// Functionality, for specifically encoding `Self` into `String` /// after serialization by using `serde::Serialize` /// specifically, to convert into JSON `String`. - /// fn encode_to_string_of_json(&'e self) -> CustomResult where Self: Serialize; - /// /// Functionality, for specifically encoding `Self` into `String` /// after serialization by using `serde::Serialize` /// specifically, to convert into XML `String`. - /// fn encode_to_string_of_xml(&'e self) -> CustomResult where Self: Serialize; - /// /// Functionality, for specifically encoding `Self` into `serde_json::Value` /// after serialization by using `serde::Serialize` - /// fn encode_to_value(&'e self) -> CustomResult where Self: Serialize; - /// /// Functionality, for specifically encoding `Self` into `Vec` /// after serialization by using `serde::Serialize` - /// fn encode_to_vec(&'e self) -> CustomResult, errors::ParsingError> where Self: Serialize; @@ -165,13 +148,9 @@ where } } -/// /// Extending functionalities of `bytes::Bytes` -/// pub trait BytesExt { - /// /// Convert `bytes::Bytes` into type `` using `serde::Deserialize` - /// fn parse_struct<'de, T>( &'de self, type_name: &'static str, @@ -199,13 +178,9 @@ impl BytesExt for bytes::Bytes { } } -/// /// Extending functionalities of `[u8]` for performing parsing -/// pub trait ByteSliceExt { - /// /// Convert `[u8]` into type `` by using `serde::Deserialize` - /// fn parse_struct<'de, T>( &'de self, type_name: &'static str, @@ -229,13 +204,9 @@ impl ByteSliceExt for [u8] { } } -/// /// Extending functionalities of `serde_json::Value` for performing parsing -/// pub trait ValueExt { - /// /// Convert `serde_json::Value` into type `` by using `serde::Deserialize` - /// fn parse_value(self, type_name: &'static str) -> CustomResult where T: serde::de::DeserializeOwned; @@ -277,22 +248,16 @@ impl ValueExt for crypto::Encryptable { } } -/// /// Extending functionalities of `String` for performing parsing -/// pub trait StringExt { - /// /// Convert `String` into type `` (which being an `enum`) - /// fn parse_enum(self, enum_name: &'static str) -> CustomResult where T: std::str::FromStr, // Requirement for converting the `Err` variant of `FromStr` to `Report` ::Err: std::error::Error + Send + Sync + 'static; - /// /// Convert `serde_json::Value` into type `` by using `serde::Deserialize` - /// fn parse_struct<'de>( &'de self, type_name: &'static str, @@ -327,25 +292,20 @@ impl StringExt for String { } } -/// /// Extending functionalities of Wrapper types for idiomatic -/// #[cfg(feature = "async_ext")] #[cfg_attr(feature = "async_ext", async_trait::async_trait)] pub trait AsyncExt { /// Output type of the map function type WrappedSelf; - /// + /// Extending map by allowing functions which are async - /// async fn async_map(self, func: F) -> Self::WrappedSelf where F: FnOnce(A) -> Fut + Send, Fut: futures::Future + Send; - /// /// Extending the `and_then` by allowing functions which are async - /// async fn async_and_then(self, func: F) -> Self::WrappedSelf where F: FnOnce(A) -> Fut + Send, @@ -469,9 +429,7 @@ where /// Extension trait for deserializing XML strings using `quick-xml` crate pub trait XmlExt { - /// /// Deserialize an XML string into the specified type ``. - /// fn parse_xml(self) -> Result where T: serde::de::DeserializeOwned; diff --git a/crates/common_utils/src/pii.rs b/crates/common_utils/src/pii.rs index 9d4b96200ba7..5fd0e8078a25 100644 --- a/crates/common_utils/src/pii.rs +++ b/crates/common_utils/src/pii.rs @@ -348,7 +348,6 @@ where } /// Strategy for masking UPI VPA's - #[derive(Debug)] pub enum UpiVpaMaskingStrategy {} diff --git a/crates/common_utils/src/signals.rs b/crates/common_utils/src/signals.rs index 5bde366bf3c5..d008aef290e8 100644 --- a/crates/common_utils/src/signals.rs +++ b/crates/common_utils/src/signals.rs @@ -6,10 +6,8 @@ use futures::StreamExt; use router_env::logger; use tokio::sync::mpsc; -/// /// This functions is meant to run in parallel to the application. /// It will send a signal to the receiver when a SIGTERM or SIGINT is received -/// #[cfg(not(target_os = "windows"))] pub async fn signal_handler(mut sig: signal_hook_tokio::Signals, sender: mpsc::Sender<()>) { if let Some(signal) = sig.next().await { @@ -34,47 +32,35 @@ pub async fn signal_handler(mut sig: signal_hook_tokio::Signals, sender: mpsc::S } } -/// /// This functions is meant to run in parallel to the application. /// It will send a signal to the receiver when a SIGTERM or SIGINT is received -/// #[cfg(target_os = "windows")] pub async fn signal_handler(_sig: DummySignal, _sender: mpsc::Sender<()>) {} -/// /// This function is used to generate a list of signals that the signal_handler should listen for -/// #[cfg(not(target_os = "windows"))] pub fn get_allowed_signals() -> Result { signal_hook_tokio::Signals::new([signal_hook::consts::SIGTERM, signal_hook::consts::SIGINT]) } -/// /// This function is used to generate a list of signals that the signal_handler should listen for -/// #[cfg(target_os = "windows")] pub fn get_allowed_signals() -> Result { Ok(DummySignal) } -/// /// Dummy Signal Handler for windows -/// #[cfg(target_os = "windows")] #[derive(Debug, Clone)] pub struct DummySignal; #[cfg(target_os = "windows")] impl DummySignal { - /// /// Dummy handler for signals in windows (empty) - /// pub fn handle(&self) -> Self { self.clone() } - /// /// Hollow implementation, for windows compatibility - /// pub fn close(self) {} } diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 2a271acb62bb..6c4b090fff20 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -334,7 +334,6 @@ impl AmountConvertor for FloatMajorUnitForConnector { } /// Connector required amount type - #[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, Copy, PartialEq)] pub struct MinorUnitForConnector; @@ -503,7 +502,6 @@ impl Sum for MinorUnit { } /// Connector specific types to send - #[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, PartialEq)] pub struct StringMinorUnit(String); @@ -603,7 +601,6 @@ impl StringMajorUnit { pub fn zero() -> Self { Self("0".to_string()) } - /// Get string amount from struct to be removed in future pub fn get_amount_as_string(&self) -> String { self.0.clone() @@ -749,7 +746,7 @@ mod client_secret_type { { struct ClientSecretVisitor; - impl<'de> Visitor<'de> for ClientSecretVisitor { + impl Visitor<'_> for ClientSecretVisitor { type Value = ClientSecret; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/crates/common_utils/src/types/keymanager.rs b/crates/common_utils/src/types/keymanager.rs index 078f1f3fcd81..09d26bd91ef8 100644 --- a/crates/common_utils/src/types/keymanager.rs +++ b/crates/common_utils/src/types/keymanager.rs @@ -393,7 +393,7 @@ impl<'de> Deserialize<'de> for DecryptedData { { struct DecryptedDataVisitor; - impl<'de> Visitor<'de> for DecryptedDataVisitor { + impl Visitor<'_> for DecryptedDataVisitor { type Value = DecryptedData; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -449,7 +449,7 @@ impl<'de> Deserialize<'de> for EncryptedData { { struct EncryptedDataVisitor; - impl<'de> Visitor<'de> for EncryptedDataVisitor { + impl Visitor<'_> for EncryptedDataVisitor { type Value = EncryptedData; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/crates/common_utils/src/types/theme.rs b/crates/common_utils/src/types/theme.rs index 9ad9206acceb..239cffc40d45 100644 --- a/crates/common_utils/src/types/theme.rs +++ b/crates/common_utils/src/types/theme.rs @@ -1,8 +1,14 @@ -use crate::id_type; +use common_enums::EntityType; + +use crate::{ + events::{ApiEventMetric, ApiEventsType}, + id_type, impl_api_event_type, +}; /// Enum for having all the required lineage for every level. /// Currently being used for theme related APIs and queries. -#[derive(Debug)] +#[derive(Debug, serde::Deserialize, serde::Serialize)] +#[serde(tag = "entity_type", rename_all = "snake_case")] pub enum ThemeLineage { // TODO: Add back Tenant variant when we introduce Tenant Variant in EntityType // /// Tenant lineage variant @@ -38,3 +44,52 @@ pub enum ThemeLineage { profile_id: id_type::ProfileId, }, } + +impl_api_event_type!(Miscellaneous, (ThemeLineage)); + +impl ThemeLineage { + /// Get the entity_type from the lineage + pub fn entity_type(&self) -> EntityType { + match self { + Self::Organization { .. } => EntityType::Organization, + Self::Merchant { .. } => EntityType::Merchant, + Self::Profile { .. } => EntityType::Profile, + } + } + + /// Get the tenant_id from the lineage + pub fn tenant_id(&self) -> &id_type::TenantId { + match self { + Self::Organization { tenant_id, .. } + | Self::Merchant { tenant_id, .. } + | Self::Profile { tenant_id, .. } => tenant_id, + } + } + + /// Get the org_id from the lineage + pub fn org_id(&self) -> Option<&id_type::OrganizationId> { + match self { + Self::Organization { org_id, .. } + | Self::Merchant { org_id, .. } + | Self::Profile { org_id, .. } => Some(org_id), + } + } + + /// Get the merchant_id from the lineage + pub fn merchant_id(&self) -> Option<&id_type::MerchantId> { + match self { + Self::Organization { .. } => None, + Self::Merchant { merchant_id, .. } | Self::Profile { merchant_id, .. } => { + Some(merchant_id) + } + } + } + + /// Get the profile_id from the lineage + pub fn profile_id(&self) -> Option<&id_type::ProfileId> { + match self { + Self::Organization { .. } | Self::Merchant { .. } => None, + Self::Profile { profile_id, .. } => Some(profile_id), + } + } +} diff --git a/crates/connector_configs/src/common_config.rs b/crates/connector_configs/src/common_config.rs index 26c9d33f405a..8f6e03fb3987 100644 --- a/crates/connector_configs/src/common_config.rs +++ b/crates/connector_configs/src/common_config.rs @@ -106,7 +106,6 @@ pub struct ApiModelMetaData { #[serde_with::skip_serializing_none] #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] - pub enum KlarnaEndpoint { Europe, NorthAmerica, diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs index 0e68b04d27b4..c1f7cfc366c7 100644 --- a/crates/connector_configs/src/connector.rs +++ b/crates/connector_configs/src/connector.rs @@ -73,7 +73,6 @@ pub enum ApplePayTomlConfig { #[serde_with::skip_serializing_none] #[derive(Debug, Clone, serde::Serialize, Deserialize)] - pub enum KlarnaEndpoint { Europe, NorthAmerica, @@ -121,6 +120,7 @@ pub struct ConfigMetadata { #[derive(Debug, Deserialize, serde::Serialize, Clone)] pub struct ConnectorWalletDetailsConfig { pub samsung_pay: Option>, + pub paze: Option>, } #[serde_with::skip_serializing_none] diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml index fc4805b2b265..35affbf74209 100644 --- a/crates/connector_configs/toml/development.toml +++ b/crates/connector_configs/toml/development.toml @@ -1367,6 +1367,25 @@ required=true type="MultiSelect" options=["visa","masterCard","amex","discover"] +[[cybersource.connector_wallets_details.paze]] +name="client_id" +label="Client Id" +placeholder="Enter paze Client Id" +required=true +type="Text" +[[cybersource.connector_wallets_details.paze]] +name="client_profile_id" +label="Client Profile Id" +placeholder="Enter Client Profile Id" +required=true +type="Text" +[[cybersource.connector_wallets_details.paze]] +name="client_name" +label="Display Name" +placeholder="Enter Display Name" +required=true +type="Text" + [cybersource.metadata.acquirer_bin] name="acquirer_bin" label="Acquirer Bin" diff --git a/crates/diesel_models/src/configs.rs b/crates/diesel_models/src/configs.rs index 2b30aa6a9724..37381961d967 100644 --- a/crates/diesel_models/src/configs.rs +++ b/crates/diesel_models/src/configs.rs @@ -7,7 +7,6 @@ use crate::schema::configs; #[derive(Default, Clone, Debug, Insertable, Serialize, Deserialize)] #[diesel(table_name = configs)] - pub struct ConfigNew { pub key: String, pub config: String, diff --git a/crates/diesel_models/src/gsm.rs b/crates/diesel_models/src/gsm.rs index 6a444410fa8f..aba8d75a6ebb 100644 --- a/crates/diesel_models/src/gsm.rs +++ b/crates/diesel_models/src/gsm.rs @@ -1,5 +1,6 @@ //! Gateway status mapping +use common_enums::ErrorCategory; use common_utils::{ custom_serde, events::{ApiEventMetric, ApiEventsType}, @@ -39,6 +40,7 @@ pub struct GatewayStatusMap { pub step_up_possible: bool, pub unified_code: Option, pub unified_message: Option, + pub error_category: Option, } #[derive(Clone, Debug, Eq, PartialEq, Insertable)] @@ -55,17 +57,11 @@ pub struct GatewayStatusMappingNew { pub step_up_possible: bool, pub unified_code: Option, pub unified_message: Option, + pub error_category: Option, } #[derive( - Clone, - Debug, - PartialEq, - Eq, - AsChangeset, - router_derive::DebugAsDisplay, - Default, - serde::Deserialize, + Clone, Debug, PartialEq, Eq, AsChangeset, router_derive::DebugAsDisplay, serde::Deserialize, )] #[diesel(table_name = gateway_status_map)] pub struct GatewayStatusMapperUpdateInternal { @@ -80,6 +76,8 @@ pub struct GatewayStatusMapperUpdateInternal { pub step_up_possible: Option, pub unified_code: Option, pub unified_message: Option, + pub error_category: Option, + pub last_modified: PrimitiveDateTime, } #[derive(Debug)] @@ -90,6 +88,7 @@ pub struct GatewayStatusMappingUpdate { pub step_up_possible: Option, pub unified_code: Option, pub unified_message: Option, + pub error_category: Option, } impl From for GatewayStatusMapperUpdateInternal { @@ -101,6 +100,7 @@ impl From for GatewayStatusMapperUpdateInternal { step_up_possible, unified_code, unified_message, + error_category, } = value; Self { status, @@ -109,7 +109,13 @@ impl From for GatewayStatusMapperUpdateInternal { step_up_possible, unified_code, unified_message, - ..Default::default() + error_category, + last_modified: common_utils::date_time::now(), + connector: None, + flow: None, + sub_flow: None, + code: None, + message: None, } } } diff --git a/crates/diesel_models/src/lib.rs b/crates/diesel_models/src/lib.rs index c7a3818d5fea..7e476662ea7a 100644 --- a/crates/diesel_models/src/lib.rs +++ b/crates/diesel_models/src/lib.rs @@ -75,7 +75,6 @@ pub use self::{ /// `Option` values. /// /// [diesel-2.0-array-nullability]: https://diesel.rs/guides/migration_guide.html#2-0-0-nullability-of-array-elements - #[doc(hidden)] pub(crate) mod diesel_impl { use diesel::{ diff --git a/crates/diesel_models/src/organization.rs b/crates/diesel_models/src/organization.rs index bd4fd1192017..6a3cad24e1c6 100644 --- a/crates/diesel_models/src/organization.rs +++ b/crates/diesel_models/src/organization.rs @@ -197,8 +197,8 @@ impl From for OrganizationUpdateInternal { } } } -#[cfg(feature = "v2")] +#[cfg(feature = "v2")] impl From for OrganizationUpdateInternal { fn from(value: OrganizationUpdate) -> Self { match value { diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 7760ea76c500..6ddc26d49bdb 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -6,7 +6,7 @@ use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable}; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; -use crate::enums::{self as storage_enums}; +use crate::enums as storage_enums; #[cfg(feature = "v1")] use crate::schema::payment_attempt; #[cfg(feature = "v2")] diff --git a/crates/diesel_models/src/query/user/theme.rs b/crates/diesel_models/src/query/user/theme.rs index 78fd5025ef98..a26e401ffbb3 100644 --- a/crates/diesel_models/src/query/user/theme.rs +++ b/crates/diesel_models/src/query/user/theme.rs @@ -69,6 +69,14 @@ impl Theme { } } + pub async fn find_by_theme_id(conn: &PgPooledConn, theme_id: String) -> StorageResult { + generics::generic_find_one::<::Table, _, _>( + conn, + dsl::theme_id.eq(theme_id), + ) + .await + } + pub async fn find_by_lineage( conn: &PgPooledConn, lineage: ThemeLineage, diff --git a/crates/diesel_models/src/reverse_lookup.rs b/crates/diesel_models/src/reverse_lookup.rs index 87fca3440784..974851f966a1 100644 --- a/crates/diesel_models/src/reverse_lookup.rs +++ b/crates/diesel_models/src/reverse_lookup.rs @@ -2,7 +2,6 @@ use diesel::{Identifiable, Insertable, Queryable, Selectable}; use crate::schema::reverse_lookup; -/// /// This reverse lookup table basically looks up id's and get result_id that you want. This is /// useful for KV where you can't lookup without key #[derive( diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs index d3e560fc048c..b6f1a4f8d05e 100644 --- a/crates/diesel_models/src/schema.rs +++ b/crates/diesel_models/src/schema.rs @@ -508,6 +508,8 @@ diesel::table! { unified_code -> Nullable, #[max_length = 1024] unified_message -> Nullable, + #[max_length = 64] + error_category -> Nullable, } } diff --git a/crates/diesel_models/src/schema_v2.rs b/crates/diesel_models/src/schema_v2.rs index f6bab9071cd0..470868ed82d4 100644 --- a/crates/diesel_models/src/schema_v2.rs +++ b/crates/diesel_models/src/schema_v2.rs @@ -520,6 +520,8 @@ diesel::table! { unified_code -> Nullable, #[max_length = 1024] unified_message -> Nullable, + #[max_length = 64] + error_category -> Nullable, } } diff --git a/crates/diesel_models/src/services/logger.rs b/crates/diesel_models/src/services/logger.rs deleted file mode 100644 index 9c1b20c9d280..000000000000 --- a/crates/diesel_models/src/services/logger.rs +++ /dev/null @@ -1,5 +0,0 @@ -//! -//! Logger of the system. -//! - -pub use crate::env::logger::*; diff --git a/crates/diesel_models/src/user/theme.rs b/crates/diesel_models/src/user/theme.rs index 9841e21443c0..e43a182126b7 100644 --- a/crates/diesel_models/src/user/theme.rs +++ b/crates/diesel_models/src/user/theme.rs @@ -1,5 +1,5 @@ use common_enums::EntityType; -use common_utils::id_type; +use common_utils::{date_time, id_type, types::theme::ThemeLineage}; use diesel::{Identifiable, Insertable, Queryable, Selectable}; use time::PrimitiveDateTime; @@ -32,3 +32,21 @@ pub struct ThemeNew { pub entity_type: EntityType, pub theme_name: String, } + +impl ThemeNew { + pub fn new(theme_id: String, theme_name: String, lineage: ThemeLineage) -> Self { + let now = date_time::now(); + + Self { + theme_id, + theme_name, + tenant_id: lineage.tenant_id().to_owned(), + org_id: lineage.org_id().cloned(), + merchant_id: lineage.merchant_id().cloned(), + profile_id: lineage.profile_id().cloned(), + entity_type: lineage.entity_type(), + created_at: now, + last_modified_at: now, + } + } +} diff --git a/crates/drainer/src/services.rs b/crates/drainer/src/services.rs index 55ffe0c4e7fa..87057ebeff2d 100644 --- a/crates/drainer/src/services.rs +++ b/crates/drainer/src/services.rs @@ -29,7 +29,6 @@ impl Store { /// /// Panics if there is a failure while obtaining the HashiCorp client using the provided configuration. /// This panic indicates a critical failure in setting up external services, and the application cannot proceed without a valid HashiCorp client. - /// pub async fn new(config: &crate::Settings, test_transaction: bool, tenant: &Tenant) -> Self { let redis_conn = crate::connection::redis_connection(config).await; Self { diff --git a/crates/euclid/src/dssa/analyzer.rs b/crates/euclid/src/dssa/analyzer.rs index a81e7be351fb..7aeb850e1bb0 100644 --- a/crates/euclid/src/dssa/analyzer.rs +++ b/crates/euclid/src/dssa/analyzer.rs @@ -87,7 +87,7 @@ pub fn analyze_exhaustive_negations( .cloned() .unwrap_or_default() .iter() - .cloned() + .copied() .cloned() .collect(), }; @@ -121,12 +121,12 @@ fn analyze_negated_assertions( value: (*val).clone(), assertion_metadata: assertion_metadata .get(*val) - .cloned() + .copied() .cloned() .unwrap_or_default(), negation_metadata: negation_metadata .get(*val) - .cloned() + .copied() .cloned() .unwrap_or_default(), }; diff --git a/crates/euclid/src/dssa/graph.rs b/crates/euclid/src/dssa/graph.rs index 30d71090f365..7ef9bb244d98 100644 --- a/crates/euclid/src/dssa/graph.rs +++ b/crates/euclid/src/dssa/graph.rs @@ -421,7 +421,7 @@ impl CgraphExt for cgraph::ConstraintGraph { for (key, negation_set) in keywise_negation { let all_metadata = keywise_metadata.remove(&key).unwrap_or_default(); - let first_metadata = all_metadata.first().cloned().cloned().unwrap_or_default(); + let first_metadata = all_metadata.first().copied().cloned().unwrap_or_default(); self.key_analysis(key.clone(), analysis_ctx, memo, cycle_map, domains) .map_err(|e| AnalysisError::assertion_from_graph_error(&first_metadata, e))?; diff --git a/crates/euclid/src/dssa/types.rs b/crates/euclid/src/dssa/types.rs index df54de2dd998..f8340c315097 100644 --- a/crates/euclid/src/dssa/types.rs +++ b/crates/euclid/src/dssa/types.rs @@ -18,7 +18,7 @@ pub enum CtxValueKind<'a> { Negation(&'a [dir::DirValue]), } -impl<'a> CtxValueKind<'a> { +impl CtxValueKind<'_> { pub fn get_assertion(&self) -> Option<&dir::DirValue> { if let Self::Assertion(val) = self { Some(val) diff --git a/crates/euclid/src/frontend/ast.rs b/crates/euclid/src/frontend/ast.rs index 5a7b88acfbc2..7c75ad000bf8 100644 --- a/crates/euclid/src/frontend/ast.rs +++ b/crates/euclid/src/frontend/ast.rs @@ -135,7 +135,6 @@ pub struct IfStatement { /// } /// } /// ``` - #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] #[aliases(RuleConnectorSelection = Rule)] diff --git a/crates/euclid/src/frontend/ast/lowering.rs b/crates/euclid/src/frontend/ast/lowering.rs index 24fc1e80428b..ec629358d5fe 100644 --- a/crates/euclid/src/frontend/ast/lowering.rs +++ b/crates/euclid/src/frontend/ast/lowering.rs @@ -25,7 +25,6 @@ use crate::{ /// This serves for the purpose were we have the DirKey as an explicit Enum type and value as one /// of the member of the same Enum. /// So particularly it lowers a predefined Enum from DirKey to an Enum of DirValue. - macro_rules! lower_enum { ($key:ident, $value:ident) => { match $value { @@ -70,7 +69,6 @@ macro_rules! lower_enum { /// This is for the cases in which there are numerical values involved and they are lowered /// accordingly on basis of the supplied key, currently payment_amount is the only key having this /// use case - macro_rules! lower_number { ($key:ident, $value:ident, $comp:ident) => { match $value { @@ -117,7 +115,6 @@ macro_rules! lower_number { /// /// This serves for the purpose were we have the DirKey as Card_bin and value as an arbitrary string /// So particularly it lowers an arbitrary value to a predefined key. - macro_rules! lower_str { ($key:ident, $value:ident $(, $validation_closure:expr)?) => { match $value { @@ -155,7 +152,6 @@ macro_rules! lower_metadata { /// by throwing required errors for comparisons that can't be performed for a certain value type /// for example /// can't have greater/less than operations on enum types - fn lower_comparison_inner( comp: ast::Comparison, ) -> Result, AnalysisErrorType> { diff --git a/crates/euclid/src/frontend/ast/parser.rs b/crates/euclid/src/frontend/ast/parser.rs index 0c586e178e69..63a0ea08b8b6 100644 --- a/crates/euclid/src/frontend/ast/parser.rs +++ b/crates/euclid/src/frontend/ast/parser.rs @@ -51,9 +51,9 @@ impl EuclidParsable for DummyOutput { )(input) } } -pub fn skip_ws<'a, F, O>(inner: F) -> impl FnMut(&'a str) -> ParseResult<&str, O> +pub fn skip_ws<'a, F, O>(inner: F) -> impl FnMut(&'a str) -> ParseResult<&'a str, O> where - F: FnMut(&'a str) -> ParseResult<&str, O> + 'a, + F: FnMut(&'a str) -> ParseResult<&'a str, O> + 'a, { sequence::preceded(pchar::multispace0, inner) } diff --git a/crates/events/src/lib.rs b/crates/events/src/lib.rs index 3d333ec54b9d..38a597e030ba 100644 --- a/crates/events/src/lib.rs +++ b/crates/events/src/lib.rs @@ -2,14 +2,12 @@ #![cfg_attr(docsrs, doc(cfg_hide(doc)))] #![warn(missing_docs)] -//! //! A generic event handler system. //! This library consists of 4 parts: //! Event Sink: A trait that defines how events are published. This could be a simple logger, a message queue, or a database. //! EventContext: A struct that holds the event sink and metadata about the event. This is used to create events. This can be used to add metadata to all events, such as the user who triggered the event. //! EventInfo: A trait that defines the metadata that is sent with the event. It works with the EventContext to add metadata to all events. //! Event: A trait that defines the event itself. This trait is used to define the data that is sent with the event and defines the event's type & identifier. -//! mod actix; diff --git a/crates/external_services/src/file_storage.rs b/crates/external_services/src/file_storage.rs index e551cfee2af0..479b7c5f386c 100644 --- a/crates/external_services/src/file_storage.rs +++ b/crates/external_services/src/file_storage.rs @@ -1,6 +1,4 @@ -//! //! Module for managing file storage operations with support for multiple storage schemes. -//! use std::{ fmt::{Display, Formatter}, diff --git a/crates/external_services/src/file_storage/file_system.rs b/crates/external_services/src/file_storage/file_system.rs index e3986abf0f86..19b3185e81b4 100644 --- a/crates/external_services/src/file_storage/file_system.rs +++ b/crates/external_services/src/file_storage/file_system.rs @@ -1,6 +1,4 @@ -//! //! Module for local file system storage operations -//! use std::{ fs::{remove_file, File}, diff --git a/crates/external_services/src/hashicorp_vault/core.rs b/crates/external_services/src/hashicorp_vault/core.rs index 15edcb6418cd..3cc03b4330b1 100644 --- a/crates/external_services/src/hashicorp_vault/core.rs +++ b/crates/external_services/src/hashicorp_vault/core.rs @@ -103,7 +103,6 @@ impl HashiCorpVault { /// # Parameters /// /// - `config`: A reference to a `HashiCorpVaultConfig` containing the configuration details. - /// pub fn new(config: &HashiCorpVaultConfig) -> error_stack::Result { VaultClient::new( VaultClientSettingsBuilder::default() @@ -129,7 +128,6 @@ impl HashiCorpVault { /// /// - `En`: The engine type that implements the `Engine` trait. /// - `I`: The type that can be constructed from the retrieved encoded data. - /// pub async fn fetch(&self, data: String) -> error_stack::Result where for<'a> En: Engine< diff --git a/crates/external_services/src/managers/encryption_management.rs b/crates/external_services/src/managers/encryption_management.rs index 678239c60b1a..a0add638235c 100644 --- a/crates/external_services/src/managers/encryption_management.rs +++ b/crates/external_services/src/managers/encryption_management.rs @@ -1,6 +1,4 @@ -//! //! Encryption management util module -//! use std::sync::Arc; diff --git a/crates/external_services/src/managers/secrets_management.rs b/crates/external_services/src/managers/secrets_management.rs index b79046b4c75f..7b27e74bf34b 100644 --- a/crates/external_services/src/managers/secrets_management.rs +++ b/crates/external_services/src/managers/secrets_management.rs @@ -1,6 +1,4 @@ -//! //! Secrets management util module -//! use common_utils::errors::CustomResult; #[cfg(feature = "hashicorp-vault")] diff --git a/crates/external_services/src/no_encryption.rs b/crates/external_services/src/no_encryption.rs index 17c29618f89a..6f805fc7a10f 100644 --- a/crates/external_services/src/no_encryption.rs +++ b/crates/external_services/src/no_encryption.rs @@ -1,6 +1,4 @@ -//! //! No encryption functionalities -//! pub mod core; diff --git a/crates/hyperswitch_connectors/Cargo.toml b/crates/hyperswitch_connectors/Cargo.toml index 5f4def7587aa..664c78a5f45d 100644 --- a/crates/hyperswitch_connectors/Cargo.toml +++ b/crates/hyperswitch_connectors/Cargo.toml @@ -28,6 +28,7 @@ rand = "0.8.5" regex = "1.10.4" reqwest = { version = "0.11.27" } ring = "0.17.8" +roxmltree = "0.19.0" serde = { version = "1.0.197", features = ["derive"] } serde_json = "1.0.115" serde_urlencoded = "0.7.1" diff --git a/crates/hyperswitch_connectors/src/connectors.rs b/crates/hyperswitch_connectors/src/connectors.rs index fdd87a25e8a5..5b7075cd680a 100644 --- a/crates/hyperswitch_connectors/src/connectors.rs +++ b/crates/hyperswitch_connectors/src/connectors.rs @@ -1,8 +1,10 @@ pub mod airwallex; pub mod amazonpay; pub mod bambora; +pub mod bamboraapac; pub mod billwerk; pub mod bitpay; +pub mod boku; pub mod cashtocode; pub mod coinbase; pub mod cryptopay; @@ -15,6 +17,7 @@ pub mod fiservemea; pub mod fiuu; pub mod forte; pub mod globepay; +pub mod gocardless; pub mod helcim; pub mod inespay; pub mod jpmorgan; @@ -27,6 +30,8 @@ pub mod novalnet; pub mod payeezy; pub mod payu; pub mod powertranz; +pub mod prophetpay; +pub mod rapyd; pub mod razorpay; pub mod redsys; pub mod shift4; @@ -43,13 +48,14 @@ pub mod zen; pub mod zsl; pub use self::{ - airwallex::Airwallex, amazonpay::Amazonpay, bambora::Bambora, billwerk::Billwerk, - bitpay::Bitpay, cashtocode::Cashtocode, coinbase::Coinbase, cryptopay::Cryptopay, - deutschebank::Deutschebank, digitalvirgo::Digitalvirgo, dlocal::Dlocal, elavon::Elavon, - fiserv::Fiserv, fiservemea::Fiservemea, fiuu::Fiuu, forte::Forte, globepay::Globepay, - helcim::Helcim, inespay::Inespay, jpmorgan::Jpmorgan, mollie::Mollie, - multisafepay::Multisafepay, nexinets::Nexinets, nexixpay::Nexixpay, nomupay::Nomupay, - novalnet::Novalnet, payeezy::Payeezy, payu::Payu, powertranz::Powertranz, razorpay::Razorpay, + airwallex::Airwallex, amazonpay::Amazonpay, bambora::Bambora, bamboraapac::Bamboraapac, + billwerk::Billwerk, bitpay::Bitpay, boku::Boku, cashtocode::Cashtocode, coinbase::Coinbase, + cryptopay::Cryptopay, deutschebank::Deutschebank, digitalvirgo::Digitalvirgo, dlocal::Dlocal, + elavon::Elavon, fiserv::Fiserv, fiservemea::Fiservemea, fiuu::Fiuu, forte::Forte, + globepay::Globepay, gocardless::Gocardless, helcim::Helcim, inespay::Inespay, + jpmorgan::Jpmorgan, mollie::Mollie, multisafepay::Multisafepay, nexinets::Nexinets, + nexixpay::Nexixpay, nomupay::Nomupay, novalnet::Novalnet, payeezy::Payeezy, payu::Payu, + powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd, razorpay::Razorpay, redsys::Redsys, shift4::Shift4, square::Square, stax::Stax, taxjar::Taxjar, thunes::Thunes, tsys::Tsys, volt::Volt, worldline::Worldline, worldpay::Worldpay, xendit::Xendit, zen::Zen, zsl::Zsl, diff --git a/crates/router/src/connector/bamboraapac.rs b/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs similarity index 70% rename from crates/router/src/connector/bamboraapac.rs rename to crates/hyperswitch_connectors/src/connectors/bamboraapac.rs index 82ed134a9756..16ecee19eea8 100644 --- a/crates/router/src/connector/bamboraapac.rs +++ b/crates/hyperswitch_connectors/src/connectors/bamboraapac.rs @@ -1,28 +1,48 @@ pub mod transformers; +use api_models::webhooks::{IncomingWebhookEvent, ObjectReferenceId}; +use common_enums::enums; use common_utils::{ - self, - ext_traits::XmlExt, + errors::CustomResult, + ext_traits::{BytesExt, XmlExt}, + request::{Method, Request, RequestBuilder, RequestContent}, types::{AmountConvertor, MinorUnit, MinorUnitForConnector}, }; -use diesel_models::enums; use error_stack::{report, Report, ResultExt}; -use hyperswitch_interfaces::consts; +use hyperswitch_domain_models::{ + payment_method_data::PaymentMethodData, + router_data::{AccessToken, ErrorResponse, RouterData}, + router_flow_types::{ + access_token_auth::AccessTokenAuth, + payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, + refunds::{Execute, RSync}, + }, + router_request_types::{ + AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData, + PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData, + RefundsData, SetupMandateRequestData, + }, + router_response_types::{PaymentsResponseData, RefundsResponseData}, + types::{ + PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData, + RefundExecuteRouterData, RefundSyncRouterData, SetupMandateRouterData, + }, +}; +use hyperswitch_interfaces::{ + api::{self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorValidation}, + configs::Connectors, + consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE}, + errors, + events::connector_api_logs::ConnectorEvent, + types::{self, Response}, + webhooks::{IncomingWebhook, IncomingWebhookRequestDetails}, +}; use transformers as bamboraapac; use crate::{ - configs::settings, - connector::utils as connector_utils, - core::errors::{self, CustomResult}, - events::connector_api_logs::ConnectorEvent, - headers, - services::{self, request, ConnectorIntegration, ConnectorValidation}, - types::{ - self, - api::{self, ConnectorCommon, ConnectorCommonExt}, - ErrorResponse, RequestContent, Response, - }, - utils::{self, BytesExt}, + constants::headers, + types::ResponseRouterData, + utils::{self, construct_not_implemented_error_report, convert_amount}, }; #[derive(Clone)] @@ -51,12 +71,8 @@ impl api::RefundExecute for Bamboraapac {} impl api::RefundSync for Bamboraapac {} impl api::PaymentToken for Bamboraapac {} -impl - ConnectorIntegration< - api::PaymentMethodToken, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, - > for Bamboraapac +impl ConnectorIntegration + for Bamboraapac { // Not Implemented (R) } @@ -67,9 +83,9 @@ where { fn build_headers( &self, - _req: &types::RouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { let header = vec![( headers::CONTENT_TYPE.to_string(), self.get_content_type().to_string().into(), @@ -88,7 +104,7 @@ impl ConnectorValidation for Bamboraapac { match capture_method { enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( - connector_utils::construct_not_implemented_error_report(capture_method, self.id()), + construct_not_implemented_error_report(capture_method, self.id()), ), } } @@ -96,11 +112,11 @@ impl ConnectorValidation for Bamboraapac { fn validate_mandate_payment( &self, _pm_type: Option, - pm_data: types::domain::payments::PaymentMethodData, + pm_data: PaymentMethodData, ) -> CustomResult<(), errors::ConnectorError> { let connector = self.id(); match pm_data { - types::domain::payments::PaymentMethodData::Card(_) => Ok(()), + PaymentMethodData::Card(_) => Ok(()), _ => Err(errors::ConnectorError::NotSupported { message: "mandate payment".to_string(), connector, @@ -123,7 +139,7 @@ impl ConnectorCommon for Bamboraapac { "text/xml" } - fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { connectors.bamboraapac.base_url.as_ref() } @@ -146,11 +162,11 @@ impl ConnectorCommon for Bamboraapac { status_code: res.status_code, code: response_data .declined_code - .unwrap_or(consts::NO_ERROR_CODE.to_string()), + .unwrap_or(NO_ERROR_CODE.to_string()), message: response_data .declined_message .clone() - .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()), + .unwrap_or(NO_ERROR_MESSAGE.to_string()), reason: response_data.declined_message, attempt_status: None, connector_transaction_id: None, @@ -165,29 +181,20 @@ impl ConnectorCommon for Bamboraapac { } } -impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { //TODO: implement sessions flow } -impl ConnectorIntegration - for Bamboraapac -{ -} +impl ConnectorIntegration for Bamboraapac {} -impl - ConnectorIntegration< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - > for Bamboraapac +impl ConnectorIntegration + for Bamboraapac { fn get_headers( &self, - req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &SetupMandateRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -197,16 +204,16 @@ impl fn get_url( &self, - _req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, + _req: &SetupMandateRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/sipp.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::SetupMandateRouterData, - _connectors: &settings::Connectors, + req: &SetupMandateRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = bamboraapac::get_setup_mandate_body(req)?; @@ -215,12 +222,12 @@ impl fn build_request( &self, - req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &SetupMandateRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::SetupMandateType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::SetupMandateType::get_headers(self, req, connectors)?) @@ -233,10 +240,10 @@ impl fn handle_response( &self, - data: &types::SetupMandateRouterData, + data: &SetupMandateRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -248,7 +255,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -264,14 +271,12 @@ impl } } -impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { fn get_headers( &self, - req: &types::PaymentsAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -281,18 +286,18 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/dts.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::PaymentsAuthorizeRouterData, - _connectors: &settings::Connectors, + req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, ) -> CustomResult { - let amount = connector_utils::convert_amount( + let amount = convert_amount( self.amount_converter, req.request.minor_amount, req.request.currency, @@ -306,12 +311,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsAuthorizeType::get_url( self, req, connectors, )?) @@ -328,10 +333,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -343,7 +348,7 @@ impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { fn get_headers( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -376,16 +379,16 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/dts.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::PaymentsSyncRouterData, - _connectors: &settings::Connectors, + req: &PaymentsSyncRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = bamboraapac::get_payment_sync_body(req)?; @@ -394,12 +397,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) @@ -412,10 +415,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -427,7 +430,7 @@ impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { fn get_headers( &self, - req: &types::PaymentsCaptureRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -460,18 +461,18 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/dts.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::PaymentsCaptureRouterData, - _connectors: &settings::Connectors, + req: &PaymentsCaptureRouterData, + _connectors: &Connectors, ) -> CustomResult { - let amount = connector_utils::convert_amount( + let amount = convert_amount( self.amount_converter, req.request.minor_amount_to_capture, req.request.currency, @@ -485,12 +486,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsCaptureType::get_headers( @@ -505,10 +506,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -521,7 +522,7 @@ impl ConnectorIntegration - for Bamboraapac -{ -} +impl ConnectorIntegration for Bamboraapac {} -impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { fn get_headers( &self, - req: &types::RefundExecuteRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundExecuteRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -559,18 +555,18 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/dts.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::RefundExecuteRouterData, - _connectors: &settings::Connectors, + req: &RefundExecuteRouterData, + _connectors: &Connectors, ) -> CustomResult { - let amount = connector_utils::convert_amount( + let amount = convert_amount( self.amount_converter, req.request.minor_refund_amount, req.request.currency, @@ -584,11 +580,11 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { - let request = services::RequestBuilder::new() - .method(services::Method::Post) + req: &RefundExecuteRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::RefundExecuteType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundExecuteType::get_headers( @@ -603,10 +599,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -619,7 +615,7 @@ impl ConnectorIntegration - for Bamboraapac -{ +impl ConnectorIntegration for Bamboraapac { fn get_headers( &self, - req: &types::RefundSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -652,16 +646,16 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/dts.asmx", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::RefundSyncRouterData, - _connectors: &settings::Connectors, + req: &RefundSyncRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = bamboraapac::get_refund_sync_body(req)?; @@ -670,12 +664,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::RefundSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundSyncType::get_headers(self, req, connectors)?) @@ -688,10 +682,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = html_to_xml_string_conversion( String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?, @@ -703,7 +697,7 @@ impl ConnectorIntegration, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, + _request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } diff --git a/crates/router/src/connector/bamboraapac/transformers.rs b/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs similarity index 86% rename from crates/router/src/connector/bamboraapac/transformers.rs rename to crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs index 1a254c052a49..f4399d105c5d 100644 --- a/crates/router/src/connector/bamboraapac/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/bamboraapac/transformers.rs @@ -1,13 +1,26 @@ +use common_enums::enums; use common_utils::types::MinorUnit; use error_stack::ResultExt; -use hyperswitch_interfaces::consts; +use hyperswitch_domain_models::{ + payment_method_data::PaymentMethodData, + router_data::{ConnectorAuthType, ErrorResponse, RouterData}, + router_request_types::{ + PaymentsAuthorizeData, PaymentsCaptureData, PaymentsSyncData, RefundsData, ResponseId, + SetupMandateRequestData, + }, + router_response_types::{MandateReference, PaymentsResponseData, RefundsResponseData}, + types, +}; +use hyperswitch_interfaces::{ + consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE}, + errors, +}; use masking::{PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{self, CardData, PaymentsAuthorizeRequestData, RouterData}, - core::errors, - types::{self, domain, storage::enums, transformers::ForeignFrom}, + types::ResponseRouterData, + utils::{self, CardData as _, PaymentsAuthorizeRequestData, RouterData as _}, }; type Error = error_stack::Report; @@ -92,7 +105,7 @@ fn get_transaction_body( fn get_card_data(req: &types::PaymentsAuthorizeRouterData) -> Result { let card_data = match &req.request.payment_method_data { - domain::PaymentMethodData::Card(card) => { + PaymentMethodData::Card(card) => { let card_holder_name = req.get_billing_full_name()?; if req.request.setup_future_usage == Some(enums::FutureUsage::OffSession) { @@ -132,7 +145,7 @@ fn get_card_data(req: &types::PaymentsAuthorizeRouterData) -> Result { + PaymentMethodData::MandatePayment => { format!( r#" @@ -166,11 +179,11 @@ pub struct BamboraapacAuthType { account_number: Secret, } -impl TryFrom<&types::ConnectorAuthType> for BamboraapacAuthType { +impl TryFrom<&ConnectorAuthType> for BamboraapacAuthType { type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + fn try_from(auth_type: &ConnectorAuthType) -> Result { match auth_type { - types::ConnectorAuthType::SignatureKey { + ConnectorAuthType::SignatureKey { api_key, key1, api_secret, @@ -236,21 +249,21 @@ fn get_attempt_status( impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, BamboraapacPaymentsResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, + PaymentsAuthorizeData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, BamboraapacPaymentsResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, + PaymentsAuthorizeData, + PaymentsResponseData, >, ) -> Result { let response_code = item @@ -277,7 +290,7 @@ impl .submit_single_payment_result .response .credit_card_token; - Some(types::MandateReference { + Some(MandateReference { connector_mandate_id, payment_method_id: None, mandate_metadata: None, @@ -290,8 +303,8 @@ impl if response_code == 0 { Ok(Self { status: get_attempt_status(response_code, item.data.request.capture_method), - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId( connector_transaction_id.to_owned(), ), redirection_data: Box::new(None), @@ -314,7 +327,7 @@ impl .submit_single_payment_result .response .declined_code - .unwrap_or(consts::NO_ERROR_CODE.to_string()); + .unwrap_or(NO_ERROR_CODE.to_string()); let declined_message = item .response @@ -323,10 +336,10 @@ impl .submit_single_payment_result .response .declined_message - .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()); + .unwrap_or(NO_ERROR_MESSAGE.to_string()); Ok(Self { status: get_attempt_status(response_code, item.data.request.capture_method), - response: Err(types::ErrorResponse { + response: Err(ErrorResponse { status_code: item.http_code, code, message: declined_message.to_owned(), @@ -344,7 +357,7 @@ pub fn get_setup_mandate_body(req: &types::SetupMandateRouterData) -> Result { + PaymentMethodData::Card(card) => { format!( r#" TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, BamboraapacMandateResponse, - types::SetupMandateRequestData, - types::PaymentsResponseData, + SetupMandateRequestData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, BamboraapacMandateResponse, - types::SetupMandateRequestData, - types::PaymentsResponseData, + SetupMandateRequestData, + PaymentsResponseData, >, ) -> Result { let response_code = item @@ -459,10 +472,10 @@ impl if response_code == 0 { Ok(Self { status: enums::AttemptStatus::Charged, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::NoResponseId, + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::NoResponseId, redirection_data: Box::new(None), - mandate_reference: Box::new(Some(types::MandateReference { + mandate_reference: Box::new(Some(MandateReference { connector_mandate_id: Some(connector_mandate_id), payment_method_id: None, mandate_metadata: None, @@ -481,10 +494,10 @@ impl else { Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(types::ErrorResponse { + response: Err(ErrorResponse { status_code: item.http_code, - code: consts::NO_ERROR_CODE.to_string(), - message: consts::NO_ERROR_MESSAGE.to_string(), + code: NO_ERROR_CODE.to_string(), + message: NO_ERROR_MESSAGE.to_string(), reason: None, attempt_status: None, connector_transaction_id: None, @@ -568,21 +581,21 @@ pub struct CaptureResponse { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, BamboraapacCaptureResponse, - types::PaymentsCaptureData, - types::PaymentsResponseData, + PaymentsCaptureData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, BamboraapacCaptureResponse, - types::PaymentsCaptureData, - types::PaymentsResponseData, + PaymentsCaptureData, + PaymentsResponseData, >, ) -> Result { let response_code = item @@ -608,8 +621,8 @@ impl if response_code == 0 { Ok(Self { status: enums::AttemptStatus::Charged, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId( connector_transaction_id.to_owned(), ), redirection_data: Box::new(None), @@ -632,7 +645,7 @@ impl .submit_single_capture_result .response .declined_code - .unwrap_or(consts::NO_ERROR_CODE.to_string()); + .unwrap_or(NO_ERROR_CODE.to_string()); let declined_message = item .response .body @@ -640,10 +653,10 @@ impl .submit_single_capture_result .response .declined_message - .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()); + .unwrap_or(NO_ERROR_MESSAGE.to_string()); Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(types::ErrorResponse { + response: Err(ErrorResponse { status_code: item.http_code, code, message: declined_message.to_owned(), @@ -731,34 +744,20 @@ pub struct RefundResponse { declined_message: Option, } -impl ForeignFrom for enums::RefundStatus { - fn foreign_from(item: u8) -> Self { - match item { - 0 => Self::Success, - 1 => Self::Failure, - _ => Self::Pending, - } +fn get_status(item: u8) -> enums::RefundStatus { + match item { + 0 => enums::RefundStatus::Success, + 1 => enums::RefundStatus::Failure, + _ => enums::RefundStatus::Pending, } } -impl - TryFrom< - types::ResponseRouterData< - F, - BamboraapacRefundsResponse, - types::RefundsData, - types::RefundsResponseData, - >, - > for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< - F, - BamboraapacRefundsResponse, - types::RefundsData, - types::RefundsResponseData, - >, + item: ResponseRouterData, ) -> Result { let response_code = item .response @@ -776,9 +775,9 @@ impl .receipt; Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id: connector_refund_id.to_owned(), - refund_status: enums::RefundStatus::foreign_from(response_code), + refund_status: get_status(response_code), }), ..item.data }) @@ -869,22 +868,16 @@ pub struct SyncResponse { } impl - TryFrom< - types::ResponseRouterData< - F, - BamboraapacSyncResponse, - types::PaymentsSyncData, - types::PaymentsResponseData, - >, - > for types::RouterData + TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, BamboraapacSyncResponse, - types::PaymentsSyncData, - types::PaymentsResponseData, + PaymentsSyncData, + PaymentsResponseData, >, ) -> Result { let response_code = item @@ -907,8 +900,8 @@ impl if response_code == 0 { Ok(Self { status: get_attempt_status(response_code, item.data.request.capture_method), - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId( connector_transaction_id.to_owned(), ), redirection_data: Box::new(None), @@ -932,7 +925,7 @@ impl .query_response .response .declined_code - .unwrap_or(consts::NO_ERROR_CODE.to_string()); + .unwrap_or(NO_ERROR_CODE.to_string()); let declined_message = item .response .body @@ -941,10 +934,10 @@ impl .query_response .response .declined_message - .unwrap_or(consts::NO_ERROR_MESSAGE.to_string()); + .unwrap_or(NO_ERROR_MESSAGE.to_string()); Ok(Self { status: get_attempt_status(response_code, item.data.request.capture_method), - response: Err(types::ErrorResponse { + response: Err(ErrorResponse { status_code: item.http_code, code, message: declined_message.to_owned(), @@ -997,24 +990,12 @@ pub fn get_refund_sync_body(req: &types::RefundSyncRouterData) -> Result Ok(body.as_bytes().to_vec()) } -impl - TryFrom< - types::ResponseRouterData< - F, - BamboraapacSyncResponse, - types::RefundsData, - types::RefundsResponseData, - >, - > for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< - F, - BamboraapacSyncResponse, - types::RefundsData, - types::RefundsResponseData, - >, + item: ResponseRouterData, ) -> Result { let response_code = item .response @@ -1033,9 +1014,9 @@ impl .response .receipt; Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id: connector_refund_id.to_owned(), - refund_status: enums::RefundStatus::foreign_from(response_code), + refund_status: get_status(response_code), }), ..item.data }) diff --git a/crates/router/src/connector/boku.rs b/crates/hyperswitch_connectors/src/connectors/boku.rs similarity index 71% rename from crates/router/src/connector/boku.rs rename to crates/hyperswitch_connectors/src/connectors/boku.rs index a132094693a1..d23d34e47304 100644 --- a/crates/router/src/connector/boku.rs +++ b/crates/hyperswitch_connectors/src/connectors/boku.rs @@ -1,38 +1,52 @@ pub mod transformers; +use api_models::webhooks::{IncomingWebhookEvent, ObjectReferenceId}; +use common_enums::enums; use common_utils::{ - ext_traits::XmlExt, - request::RequestContent, + errors::CustomResult, + ext_traits::{BytesExt, OptionExt, XmlExt}, + request::{Method, Request, RequestBuilder, RequestContent}, types::{AmountConvertor, MinorUnit, MinorUnitForConnector}, }; -use diesel_models::enums; use error_stack::{report, Report, ResultExt}; -use masking::{ExposeInterface, PeekInterface, Secret, WithType}; +use hyperswitch_domain_models::{ + router_data::{AccessToken, ErrorResponse, RouterData}, + router_flow_types::{ + access_token_auth::AccessTokenAuth, + payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, + refunds::{Execute, RSync}, + }, + router_request_types::{ + AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData, + PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData, + RefundsData, SetupMandateRequestData, + }, + router_response_types::{PaymentsResponseData, RefundsResponseData}, + types::{ + PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData, + RefundSyncRouterData, RefundsRouterData, + }, +}; +use hyperswitch_interfaces::{ + api::{self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorValidation}, + configs::Connectors, + consts::NO_ERROR_CODE, + errors, + events::connector_api_logs::ConnectorEvent, + types::{self, Response}, + webhooks::{IncomingWebhook, IncomingWebhookRequestDetails}, +}; +use masking::{ExposeInterface, Mask, PeekInterface, Secret, WithType}; use ring::hmac; -use router_env::metrics::add_attributes; -use roxmltree; +use router_env::{logger, metrics::add_attributes}; use time::OffsetDateTime; use transformers as boku; -use super::utils as connector_utils; use crate::{ - configs::settings, - consts, - core::errors::{self, CustomResult}, - events::connector_api_logs::ConnectorEvent, - headers, logger, - routes::metrics, - services::{ - self, - request::{self, Mask}, - ConnectorIntegration, ConnectorValidation, - }, - types::{ - self, - api::{self, ConnectorCommon, ConnectorCommonExt}, - ErrorResponse, Response, - }, - utils::{BytesExt, OptionExt}, + constants::{headers, UNSUPPORTED_ERROR_MESSAGE}, + metrics, + types::ResponseRouterData, + utils::{construct_not_supported_error_report, convert_amount}, }; #[derive(Clone)] @@ -61,12 +75,8 @@ impl api::RefundExecute for Boku {} impl api::RefundSync for Boku {} impl api::PaymentToken for Boku {} -impl - ConnectorIntegration< - api::PaymentMethodToken, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, - > for Boku +impl ConnectorIntegration + for Boku { // Not Implemented (R) } @@ -77,9 +87,9 @@ where { fn build_headers( &self, - req: &types::RouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { let connector_auth = boku::BokuAuthType::try_from(&req.connector_auth_type)?; let boku_url = Self::get_url(self, req, connectors)?; @@ -125,7 +135,7 @@ impl ConnectorCommon for Boku { "text/xml;charset=utf-8" } - fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { connectors.boku.base_url.as_ref() } @@ -167,39 +177,24 @@ impl ConnectorValidation for Boku { match capture_method { enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( - connector_utils::construct_not_supported_error_report(capture_method, self.id()), + construct_not_supported_error_report(capture_method, self.id()), ), } } } -impl ConnectorIntegration - for Boku -{ +impl ConnectorIntegration for Boku { //TODO: implement sessions flow } -impl ConnectorIntegration - for Boku -{ -} +impl ConnectorIntegration for Boku {} -impl - ConnectorIntegration< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - > for Boku -{ +impl ConnectorIntegration for Boku { fn build_request( &self, - _req: &types::RouterData< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - >, - _connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + _req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Err( errors::ConnectorError::NotImplemented("Setup Mandate flow for Boku".to_string()) .into(), @@ -207,19 +202,17 @@ impl } } -impl ConnectorIntegration - for Boku -{ +impl ConnectorIntegration for Boku { fn get_headers( &self, - req: &types::PaymentsAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } - fn get_http_method(&self) -> services::Method { - services::Method::Post + fn get_http_method(&self) -> Method { + Method::Post } fn get_content_type(&self) -> &'static str { @@ -228,8 +221,8 @@ impl ConnectorIntegration CustomResult { let boku_url = get_country_url( req.connector_meta_data.clone(), @@ -241,10 +234,10 @@ impl ConnectorIntegration CustomResult { - let amount = connector_utils::convert_amount( + let amount = convert_amount( self.amount_converter, req.request.minor_amount, req.request.currency, @@ -257,12 +250,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsAuthorizeType::get_url( self, req, connectors, )?) @@ -279,10 +272,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -291,7 +284,7 @@ impl ConnectorIntegration - for Boku -{ +impl ConnectorIntegration for Boku { fn get_headers( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -324,8 +315,8 @@ impl ConnectorIntegration CustomResult { let boku_url = get_country_url( req.connector_meta_data.clone(), @@ -337,8 +328,8 @@ impl ConnectorIntegration CustomResult { let connector_req = boku::BokuPsyncRequest::try_from(req)?; Ok(RequestContent::Xml(Box::new(connector_req))) @@ -346,12 +337,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Get) + RequestBuilder::new() + .method(Method::Get) .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) @@ -364,10 +355,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -376,7 +367,7 @@ impl ConnectorIntegration - for Boku -{ +impl ConnectorIntegration for Boku { fn get_headers( &self, - req: &types::PaymentsCaptureRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -409,28 +398,28 @@ impl ConnectorIntegration CustomResult { Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) } fn get_request_body( &self, - _req: &types::PaymentsCaptureRouterData, - _connectors: &settings::Connectors, + _req: &PaymentsCaptureRouterData, + _connectors: &Connectors, ) -> CustomResult { Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) } fn build_request( &self, - req: &types::PaymentsCaptureRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsCaptureType::get_headers( @@ -445,10 +434,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response_data = String::from_utf8(res.response.to_vec()) .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; @@ -457,7 +446,7 @@ impl ConnectorIntegration - for Boku -{ -} +impl ConnectorIntegration for Boku {} -impl ConnectorIntegration for Boku { +impl ConnectorIntegration for Boku { fn get_headers( &self, - req: &types::RefundsRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -493,8 +479,8 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, + req: &RefundsRouterData, + connectors: &Connectors, ) -> CustomResult { let boku_url = get_country_url( req.connector_meta_data.clone(), @@ -506,10 +492,10 @@ impl ConnectorIntegration, - _connectors: &settings::Connectors, + req: &RefundsRouterData, + _connectors: &Connectors, ) -> CustomResult { - let refund_amount = connector_utils::convert_amount( + let refund_amount = convert_amount( self.amount_converter, req.request.minor_refund_amount, req.request.currency, @@ -522,11 +508,11 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { - let request = services::RequestBuilder::new() - .method(services::Method::Post) + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::RefundExecuteType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundExecuteType::get_headers( @@ -541,10 +527,10 @@ impl ConnectorIntegration, + data: &RefundsRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult, errors::ConnectorError> { + ) -> CustomResult, errors::ConnectorError> { let response: boku::RefundResponse = res .response .parse_struct("boku RefundResponse") @@ -553,7 +539,7 @@ impl ConnectorIntegration for Boku { +impl ConnectorIntegration for Boku { fn get_headers( &self, - req: &types::RefundSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -584,8 +570,8 @@ impl ConnectorIntegration CustomResult { let boku_url = get_country_url( req.connector_meta_data.clone(), @@ -597,8 +583,8 @@ impl ConnectorIntegration CustomResult { let connector_req = boku::BokuRsyncRequest::try_from(req)?; Ok(RequestContent::Xml(Box::new(connector_req))) @@ -606,12 +592,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Get) + RequestBuilder::new() + .method(Method::Get) .url(&types::RefundSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundSyncType::get_headers(self, req, connectors)?) @@ -624,17 +610,17 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: boku::BokuRsyncResponse = res .response .parse_struct("boku BokuRsyncResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -651,24 +637,24 @@ impl ConnectorIntegration, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, + _request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } @@ -690,7 +676,7 @@ fn get_xml_deserialized( res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { - metrics::RESPONSE_DESERIALIZATION_FAILURE.add( + metrics::CONNECTOR_RESPONSE_DESERIALIZATION_FAILURE.add( &metrics::CONTEXT, 1, &add_attributes([("connector", "boku")]), @@ -711,8 +697,8 @@ fn get_xml_deserialized( logger::error!("UNEXPECTED RESPONSE FROM CONNECTOR: {}", response_data); Ok(ErrorResponse { status_code: res.status_code, - code: consts::NO_ERROR_CODE.to_string(), - message: consts::UNSUPPORTED_ERROR_MESSAGE.to_string(), + code: NO_ERROR_CODE.to_string(), + message: UNSUPPORTED_ERROR_MESSAGE.to_string(), reason: Some(response_data), attempt_status: None, connector_transaction_id: None, diff --git a/crates/router/src/connector/boku/transformers.rs b/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs similarity index 73% rename from crates/router/src/connector/boku/transformers.rs rename to crates/hyperswitch_connectors/src/connectors/boku/transformers.rs index 4a947284d79d..df1331750378 100644 --- a/crates/router/src/connector/boku/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/boku/transformers.rs @@ -1,16 +1,24 @@ use std::fmt; -use common_utils::types::MinorUnit; +use common_enums::enums; +use common_utils::{request::Method, types::MinorUnit}; +use hyperswitch_domain_models::{ + payment_method_data::{PaymentMethodData, WalletData}, + router_data::{ConnectorAuthType, RouterData}, + router_flow_types::refunds::{Execute, RSync}, + router_request_types::ResponseId, + router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData}, + types::{self, RefundsRouterData}, +}; +use hyperswitch_interfaces::errors; use masking::Secret; use serde::{Deserialize, Serialize}; use url::Url; use uuid::Uuid; use crate::{ - connector::utils::{self, AddressDetailsData, RouterData}, - core::errors, - services::{self, RedirectForm}, - types::{self, api, domain, storage::enums}, + types::{RefundsResponseRouterData, ResponseRouterData}, + utils::{self, AddressDetailsData, RouterData as _}, }; #[derive(Debug, Serialize)] @@ -96,25 +104,25 @@ impl TryFrom<&BokuRouterData<&types::PaymentsAuthorizeRouterData>> for BokuPayme item: &BokuRouterData<&types::PaymentsAuthorizeRouterData>, ) -> Result { match item.router_data.request.payment_method_data.clone() { - domain::PaymentMethodData::Wallet(wallet_data) => Self::try_from((item, &wallet_data)), - domain::PaymentMethodData::Card(_) - | domain::PaymentMethodData::CardRedirect(_) - | domain::PaymentMethodData::PayLater(_) - | domain::PaymentMethodData::BankRedirect(_) - | domain::PaymentMethodData::BankDebit(_) - | domain::PaymentMethodData::BankTransfer(_) - | domain::PaymentMethodData::Crypto(_) - | domain::PaymentMethodData::MandatePayment - | domain::PaymentMethodData::Reward - | domain::PaymentMethodData::RealTimePayment(_) - | domain::PaymentMethodData::MobilePayment(_) - | domain::PaymentMethodData::Upi(_) - | domain::PaymentMethodData::Voucher(_) - | domain::PaymentMethodData::GiftCard(_) - | domain::PaymentMethodData::OpenBanking(_) - | domain::PaymentMethodData::CardToken(_) - | domain::PaymentMethodData::NetworkToken(_) - | domain::PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { + PaymentMethodData::Wallet(wallet_data) => Self::try_from((item, &wallet_data)), + PaymentMethodData::Card(_) + | PaymentMethodData::CardRedirect(_) + | PaymentMethodData::PayLater(_) + | PaymentMethodData::BankRedirect(_) + | PaymentMethodData::BankDebit(_) + | PaymentMethodData::BankTransfer(_) + | PaymentMethodData::Crypto(_) + | PaymentMethodData::MandatePayment + | PaymentMethodData::Reward + | PaymentMethodData::RealTimePayment(_) + | PaymentMethodData::MobilePayment(_) + | PaymentMethodData::Upi(_) + | PaymentMethodData::Voucher(_) + | PaymentMethodData::GiftCard(_) + | PaymentMethodData::OpenBanking(_) + | PaymentMethodData::CardToken(_) + | PaymentMethodData::NetworkToken(_) + | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("boku"), ))? @@ -126,14 +134,14 @@ impl TryFrom<&BokuRouterData<&types::PaymentsAuthorizeRouterData>> for BokuPayme impl TryFrom<( &BokuRouterData<&types::PaymentsAuthorizeRouterData>, - &domain::WalletData, + &WalletData, )> for BokuPaymentsRequest { type Error = error_stack::Report; fn try_from( value: ( &BokuRouterData<&types::PaymentsAuthorizeRouterData>, - &domain::WalletData, + &WalletData, ), ) -> Result { let (item_router_data, wallet_data) = value; @@ -162,36 +170,36 @@ impl } } -fn get_wallet_type(wallet_data: &domain::WalletData) -> Result { +fn get_wallet_type(wallet_data: &WalletData) -> Result { match wallet_data { - domain::WalletData::DanaRedirect { .. } => Ok(BokuPaymentType::Dana.to_string()), - domain::WalletData::MomoRedirect { .. } => Ok(BokuPaymentType::Momo.to_string()), - domain::WalletData::GcashRedirect { .. } => Ok(BokuPaymentType::Gcash.to_string()), - domain::WalletData::GoPayRedirect { .. } => Ok(BokuPaymentType::GoPay.to_string()), - domain::WalletData::KakaoPayRedirect { .. } => Ok(BokuPaymentType::Kakaopay.to_string()), - domain::WalletData::AliPayQr(_) - | domain::WalletData::AliPayRedirect(_) - | domain::WalletData::AliPayHkRedirect(_) - | domain::WalletData::ApplePay(_) - | domain::WalletData::ApplePayRedirect(_) - | domain::WalletData::ApplePayThirdPartySdk(_) - | domain::WalletData::GooglePay(_) - | domain::WalletData::GooglePayRedirect(_) - | domain::WalletData::GooglePayThirdPartySdk(_) - | domain::WalletData::MbWayRedirect(_) - | domain::WalletData::MobilePayRedirect(_) - | domain::WalletData::PaypalRedirect(_) - | domain::WalletData::PaypalSdk(_) - | domain::WalletData::Paze(_) - | domain::WalletData::SamsungPay(_) - | domain::WalletData::TwintRedirect {} - | domain::WalletData::VippsRedirect {} - | domain::WalletData::TouchNGoRedirect(_) - | domain::WalletData::WeChatPayRedirect(_) - | domain::WalletData::WeChatPayQr(_) - | domain::WalletData::CashappQr(_) - | domain::WalletData::SwishQr(_) - | domain::WalletData::Mifinity(_) => Err(errors::ConnectorError::NotImplemented( + WalletData::DanaRedirect { .. } => Ok(BokuPaymentType::Dana.to_string()), + WalletData::MomoRedirect { .. } => Ok(BokuPaymentType::Momo.to_string()), + WalletData::GcashRedirect { .. } => Ok(BokuPaymentType::Gcash.to_string()), + WalletData::GoPayRedirect { .. } => Ok(BokuPaymentType::GoPay.to_string()), + WalletData::KakaoPayRedirect { .. } => Ok(BokuPaymentType::Kakaopay.to_string()), + WalletData::AliPayQr(_) + | WalletData::AliPayRedirect(_) + | WalletData::AliPayHkRedirect(_) + | WalletData::ApplePay(_) + | WalletData::ApplePayRedirect(_) + | WalletData::ApplePayThirdPartySdk(_) + | WalletData::GooglePay(_) + | WalletData::GooglePayRedirect(_) + | WalletData::GooglePayThirdPartySdk(_) + | WalletData::MbWayRedirect(_) + | WalletData::MobilePayRedirect(_) + | WalletData::PaypalRedirect(_) + | WalletData::PaypalSdk(_) + | WalletData::Paze(_) + | WalletData::SamsungPay(_) + | WalletData::TwintRedirect {} + | WalletData::VippsRedirect {} + | WalletData::TouchNGoRedirect(_) + | WalletData::WeChatPayRedirect(_) + | WalletData::WeChatPayQr(_) + | WalletData::CashappQr(_) + | WalletData::SwishQr(_) + | WalletData::Mifinity(_) => Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("boku"), )), } @@ -202,11 +210,11 @@ pub struct BokuAuthType { pub(super) key_id: Secret, } -impl TryFrom<&types::ConnectorAuthType> for BokuAuthType { +impl TryFrom<&ConnectorAuthType> for BokuAuthType { type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + fn try_from(auth_type: &ConnectorAuthType) -> Result { match auth_type { - types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self { + ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self { merchant_id: key1.to_owned(), key_id: api_key.to_owned(), }), @@ -286,12 +294,12 @@ pub struct SingleChargeResponseData { charge_id: String, } -impl TryFrom> - for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData, + item: ResponseRouterData, ) -> Result { let (status, transaction_id, redirection_data) = match item.response { BokuResponse::BeginSingleChargeResponse(response) => get_authorize_response(response), @@ -300,8 +308,8 @@ impl TryFrom Ok(hosted_value .redirect_url - .map(|url| RedirectForm::from((url, services::Method::Get)))), + .map(|url| RedirectForm::from((url, Method::Get)))), None => Err(errors::ConnectorError::MissingConnectorRedirectionPayload { field_name: "redirect_url", }), @@ -372,9 +380,9 @@ impl fmt::Display for BokuRefundReasonCode { } } -impl TryFrom<&BokuRouterData<&types::RefundsRouterData>> for BokuRefundRequest { +impl TryFrom<&BokuRouterData<&RefundsRouterData>> for BokuRefundRequest { type Error = error_stack::Report; - fn try_from(item: &BokuRouterData<&types::RefundsRouterData>) -> Result { + fn try_from(item: &BokuRouterData<&RefundsRouterData>) -> Result { let auth_type = BokuAuthType::try_from(&item.router_data.connector_auth_type)?; let payment_data = Self { refund_amount: item.amount, @@ -408,15 +416,13 @@ fn get_refund_status(status: String) -> enums::RefundStatus { } } -impl TryFrom> - for types::RefundsRouterData -{ +impl TryFrom> for RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id: item.response.charge_id, refund_status: get_refund_status(item.response.refund_status), }), @@ -469,15 +475,13 @@ pub struct SingleRefundResponseData { refund_id: String, } -impl TryFrom> - for types::RefundsRouterData -{ +impl TryFrom> for RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id: item.response.refunds.refund.refund_id, refund_status: get_refund_status(item.response.refunds.refund.refund_status), }), diff --git a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs index d5a7f981a1b1..433308059ae9 100644 --- a/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs @@ -1,4 +1,3 @@ -use api_models::payments::AddressDetails; use common_enums::enums; use common_utils::{pii::Email, request::Method}; use error_stack::ResultExt; @@ -182,7 +181,9 @@ impl TryFrom<&DlocalRouterData<&types::PaymentsAuthorizeRouterData>> for DlocalP } } -fn get_payer_name(address: &AddressDetails) -> Option> { +fn get_payer_name( + address: &hyperswitch_domain_models::address::AddressDetails, +) -> Option> { let first_name = address .first_name .clone() diff --git a/crates/router/src/connector/gocardless.rs b/crates/hyperswitch_connectors/src/connectors/gocardless.rs similarity index 69% rename from crates/router/src/connector/gocardless.rs rename to crates/hyperswitch_connectors/src/connectors/gocardless.rs index 281a1ea5c9b8..becc8749b5d5 100644 --- a/crates/router/src/connector/gocardless.rs +++ b/crates/hyperswitch_connectors/src/connectors/gocardless.rs @@ -2,29 +2,50 @@ pub mod transformers; use std::fmt::Debug; -use api_models::enums::enums; -use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent}; +use api_models::webhooks::{IncomingWebhookEvent, ObjectReferenceId}; +use common_enums::enums; +use common_utils::{ + crypto, + errors::CustomResult, + ext_traits::{ByteSliceExt, BytesExt}, + request::{Method, Request, RequestBuilder, RequestContent}, +}; use error_stack::ResultExt; -use masking::PeekInterface; -use transformers as gocardless; - -use crate::{ - configs::settings, - connector::utils::{self as connector_utils, PaymentMethodDataType}, - core::errors::{self, CustomResult}, - events::connector_api_logs::ConnectorEvent, - headers, - services::{ - self, - request::{self, Mask}, - ConnectorIntegration, ConnectorValidation, +use hyperswitch_domain_models::{ + payment_method_data::PaymentMethodData, + router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData}, + router_flow_types::{ + access_token_auth::AccessTokenAuth, + payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, + refunds::{Execute, RSync}, + CreateConnectorCustomer, PreProcessing, }, + router_request_types::{ + AccessTokenRequestData, ConnectorCustomerData, PaymentMethodTokenizationData, + PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsPreProcessingData, + PaymentsSessionData, PaymentsSyncData, RefundsData, SetupMandateRequestData, + }, + router_response_types::{PaymentsResponseData, RefundsResponseData}, types::{ - self, - api::{self, ConnectorCommon, ConnectorCommonExt}, - ErrorResponse, Response, + ConnectorCustomerRouterData, PaymentsAuthorizeRouterData, PaymentsSyncRouterData, + RefundSyncRouterData, RefundsRouterData, SetupMandateRouterData, TokenizationRouterData, }, - utils::BytesExt, +}; +use hyperswitch_interfaces::{ + api::{self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorValidation}, + configs::Connectors, + errors, + events::connector_api_logs::ConnectorEvent, + types::{self, PaymentsSyncType, Response}, + webhooks::{IncomingWebhook, IncomingWebhookRequestDetails}, +}; +use masking::{Mask, PeekInterface}; +use transformers as gocardless; + +use crate::{ + constants::headers, + types::ResponseRouterData, + utils::{construct_not_implemented_error_report, is_mandate_supported, PaymentMethodDataType}, }; #[derive(Debug, Clone)] @@ -54,9 +75,9 @@ where { fn build_headers( &self, - req: &types::RouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { let mut header = vec![ ( headers::CONTENT_TYPE.to_string(), @@ -86,14 +107,14 @@ impl ConnectorCommon for Gocardless { "application/json" } - fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { connectors.gocardless.base_url.as_ref() } fn get_auth_header( &self, - auth_type: &types::ConnectorAuthType, - ) -> CustomResult)>, errors::ConnectorError> { + auth_type: &ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { let auth = gocardless::GocardlessAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( @@ -134,33 +155,29 @@ impl ConnectorCommon for Gocardless { } } -impl - ConnectorIntegration< - api::CreateConnectorCustomer, - types::ConnectorCustomerData, - types::PaymentsResponseData, - > for Gocardless +impl ConnectorIntegration + for Gocardless { fn get_headers( &self, - req: &types::ConnectorCustomerRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &ConnectorCustomerRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } fn get_url( &self, - _req: &types::ConnectorCustomerRouterData, - connectors: &settings::Connectors, + _req: &ConnectorCustomerRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/customers", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::ConnectorCustomerRouterData, - _connectors: &settings::Connectors, + req: &ConnectorCustomerRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = gocardless::GocardlessCustomerRequest::try_from(req)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -168,12 +185,12 @@ impl fn build_request( &self, - req: &types::ConnectorCustomerRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &ConnectorCustomerRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::ConnectorCustomerType::get_url( self, req, connectors, )?) @@ -190,21 +207,17 @@ impl fn handle_response( &self, - data: &types::ConnectorCustomerRouterData, + data: &ConnectorCustomerRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, ) -> CustomResult< - types::RouterData< - api::CreateConnectorCustomer, - types::ConnectorCustomerData, - types::PaymentsResponseData, - >, + RouterData, errors::ConnectorError, > where - api::CreateConnectorCustomer: Clone, - types::ConnectorCustomerData: Clone, - types::PaymentsResponseData: Clone, + CreateConnectorCustomer: Clone, + ConnectorCustomerData: Clone, + PaymentsResponseData: Clone, { let response: gocardless::GocardlessCustomerResponse = res .response @@ -214,7 +227,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -230,25 +243,21 @@ impl } } -impl - ConnectorIntegration< - api::PaymentMethodToken, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, - > for Gocardless +impl ConnectorIntegration + for Gocardless { fn get_headers( &self, - req: &types::TokenizationRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &TokenizationRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } fn get_url( &self, - _req: &types::TokenizationRouterData, - connectors: &settings::Connectors, + _req: &TokenizationRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!( "{}/customer_bank_accounts", @@ -258,8 +267,8 @@ impl fn get_request_body( &self, - req: &types::TokenizationRouterData, - _connectors: &settings::Connectors, + req: &TokenizationRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = gocardless::GocardlessBankAccountRequest::try_from(req)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -267,12 +276,12 @@ impl fn build_request( &self, - req: &types::TokenizationRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &TokenizationRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::TokenizationType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::TokenizationType::get_headers(self, req, connectors)?) @@ -285,14 +294,14 @@ impl fn handle_response( &self, - data: &types::TokenizationRouterData, + data: &TokenizationRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult + ) -> CustomResult where - api::PaymentMethodToken: Clone, - types::PaymentMethodTokenizationData: Clone, - types::PaymentsResponseData: Clone, + PaymentMethodToken: Clone, + PaymentMethodTokenizationData: Clone, + PaymentsResponseData: Clone, { let response: gocardless::GocardlessBankAccountResponse = res .response @@ -302,7 +311,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -318,12 +327,8 @@ impl } } -impl - ConnectorIntegration< - api::PreProcessing, - types::PaymentsPreProcessingData, - types::PaymentsResponseData, - > for Gocardless +impl ConnectorIntegration + for Gocardless { } @@ -338,15 +343,16 @@ impl ConnectorValidation for Gocardless { enums::CaptureMethod::Automatic => Ok(()), enums::CaptureMethod::Manual | enums::CaptureMethod::ManualMultiple - | enums::CaptureMethod::Scheduled => Err( - connector_utils::construct_not_implemented_error_report(capture_method, self.id()), - ), + | enums::CaptureMethod::Scheduled => Err(construct_not_implemented_error_report( + capture_method, + self.id(), + )), } } fn validate_mandate_payment( &self, - pm_type: Option, - pm_data: types::domain::payments::PaymentMethodData, + pm_type: Option, + pm_data: PaymentMethodData, ) -> CustomResult<(), errors::ConnectorError> { let mandate_supported_pmd = std::collections::HashSet::from([ PaymentMethodDataType::SepaBankDebit, @@ -354,48 +360,39 @@ impl ConnectorValidation for Gocardless { PaymentMethodDataType::BecsBankDebit, PaymentMethodDataType::BacsBankDebit, ]); - connector_utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id()) + is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id()) } } -impl ConnectorIntegration - for Gocardless -{ +impl ConnectorIntegration for Gocardless { //TODO: implement sessions flow } -impl ConnectorIntegration - for Gocardless -{ -} +impl ConnectorIntegration for Gocardless {} -impl - ConnectorIntegration< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - > for Gocardless +impl ConnectorIntegration + for Gocardless { fn get_headers( &self, - req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &SetupMandateRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } fn get_url( &self, - _req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, + _req: &SetupMandateRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/mandates", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::SetupMandateRouterData, - _connectors: &settings::Connectors, + req: &SetupMandateRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_req = gocardless::GocardlessMandateRequest::try_from(req)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -403,14 +400,14 @@ impl fn build_request( &self, - req: &types::SetupMandateRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &SetupMandateRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { // Preprocessing flow is to create mandate, which should to be called only in case of First mandate if req.request.setup_mandate_details.is_some() { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::SetupMandateType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::SetupMandateType::get_headers(self, req, connectors)?) @@ -426,10 +423,10 @@ impl fn handle_response( &self, - data: &types::SetupMandateRouterData, + data: &SetupMandateRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: gocardless::GocardlessMandateResponse = res .response .parse_struct("GocardlessMandateResponse") @@ -438,7 +435,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -454,14 +451,12 @@ impl } } -impl ConnectorIntegration - for Gocardless -{ +impl ConnectorIntegration for Gocardless { fn get_headers( &self, - req: &types::PaymentsAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -471,16 +466,16 @@ impl ConnectorIntegration CustomResult { Ok(format!("{}/payments", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::PaymentsAuthorizeRouterData, - _connectors: &settings::Connectors, + req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_router_data = gocardless::GocardlessRouterData::try_from(( &self.get_currency_unit(), @@ -495,12 +490,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsAuthorizeType::get_url( self, req, connectors, )?) @@ -517,10 +512,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: gocardless::GocardlessPaymentsResponse = res .response .parse_struct("GocardlessPaymentsResponse") @@ -529,7 +524,7 @@ impl ConnectorIntegration - for Gocardless -{ +impl ConnectorIntegration for Gocardless { fn get_headers( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -562,8 +555,8 @@ impl ConnectorIntegration CustomResult { Ok(format!( "{}/payments/{}", @@ -577,25 +570,25 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Get) - .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) + RequestBuilder::new() + .method(Method::Get) + .url(&PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() - .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) + .headers(PaymentsSyncType::get_headers(self, req, connectors)?) .build(), )) } fn handle_response( &self, - data: &types::PaymentsSyncRouterData, + data: &PaymentsSyncRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: gocardless::GocardlessPaymentsResponse = res .response .parse_struct("GocardlessPaymentsResponse") @@ -604,7 +597,7 @@ impl ConnectorIntegration - for Gocardless -{ -} +impl ConnectorIntegration for Gocardless {} -impl ConnectorIntegration - for Gocardless -{ -} +impl ConnectorIntegration for Gocardless {} -impl ConnectorIntegration - for Gocardless -{ +impl ConnectorIntegration for Gocardless { fn get_headers( &self, - req: &types::RefundsRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -647,16 +632,16 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, + _req: &RefundsRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/refunds", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::RefundsRouterData, - _connectors: &settings::Connectors, + req: &RefundsRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_router_data = gocardless::GocardlessRouterData::try_from(( &self.get_currency_unit(), @@ -670,11 +655,11 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { - let request = services::RequestBuilder::new() - .method(services::Method::Post) + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::RefundExecuteType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundExecuteType::get_headers( @@ -689,10 +674,10 @@ impl ConnectorIntegration, + data: &RefundsRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult, errors::ConnectorError> { + ) -> CustomResult, errors::ConnectorError> { let response: gocardless::RefundResponse = res .response .parse_struct("gocardless RefundResponse") @@ -701,7 +686,7 @@ impl ConnectorIntegration - for Gocardless -{ +impl ConnectorIntegration for Gocardless { fn build_request( &self, - _req: &types::RefundSyncRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + _req: &RefundSyncRouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(None) } } #[async_trait::async_trait] -impl api::IncomingWebhook for Gocardless { +impl IncomingWebhook for Gocardless { fn get_webhook_source_verification_algorithm( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, + _request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { Ok(Box::new(crypto::HmacSha256)) } fn get_webhook_source_verification_signature( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { let signature = request @@ -759,7 +742,7 @@ impl api::IncomingWebhook for Gocardless { fn get_webhook_source_verification_message( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, _merchant_id: &common_utils::id_type::MerchantId, _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { @@ -770,8 +753,8 @@ impl api::IncomingWebhook for Gocardless { fn get_webhook_object_reference_id( &self, - request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { let details: gocardless::GocardlessWebhookEvent = request .body .parse_struct("GocardlessWebhookEvent") @@ -785,18 +768,18 @@ impl api::IncomingWebhook for Gocardless { let payment_id = api_models::payments::PaymentIdType::ConnectorTransactionId( link.payment.to_owned(), ); - api::webhooks::ObjectReferenceId::PaymentId(payment_id) + ObjectReferenceId::PaymentId(payment_id) } transformers::WebhooksLink::RefundWebhookLink(link) => { let refund_id = api_models::webhooks::RefundIdType::ConnectorRefundId(link.refund.to_owned()); - api::webhooks::ObjectReferenceId::RefundId(refund_id) + ObjectReferenceId::RefundId(refund_id) } transformers::WebhooksLink::MandateWebhookLink(link) => { let mandate_id = api_models::webhooks::MandateIdType::ConnectorMandateId( link.mandate.to_owned(), ); - api::webhooks::ObjectReferenceId::MandateId(mandate_id) + ObjectReferenceId::MandateId(mandate_id) } }; Ok(reference_id) @@ -804,8 +787,8 @@ impl api::IncomingWebhook for Gocardless { fn get_webhook_event_type( &self, - request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { let details: gocardless::GocardlessWebhookEvent = request .body .parse_struct("GocardlessWebhookEvent") @@ -819,41 +802,37 @@ impl api::IncomingWebhook for Gocardless { transformers::PaymentsAction::Created | transformers::PaymentsAction::Submitted | transformers::PaymentsAction::CustomerApprovalGranted => { - api::IncomingWebhookEvent::PaymentIntentProcessing + IncomingWebhookEvent::PaymentIntentProcessing } transformers::PaymentsAction::CustomerApprovalDenied | transformers::PaymentsAction::Failed | transformers::PaymentsAction::Cancelled | transformers::PaymentsAction::LateFailureSettled => { - api::IncomingWebhookEvent::PaymentIntentFailure + IncomingWebhookEvent::PaymentIntentFailure } transformers::PaymentsAction::Confirmed | transformers::PaymentsAction::PaidOut => { - api::IncomingWebhookEvent::PaymentIntentSuccess + IncomingWebhookEvent::PaymentIntentSuccess } transformers::PaymentsAction::SurchargeFeeDebited | transformers::PaymentsAction::ResubmissionRequired => { - api::IncomingWebhookEvent::EventNotSupported + IncomingWebhookEvent::EventNotSupported } }, transformers::WebhookAction::RefundsAction(action) => match action { - transformers::RefundsAction::Failed => api::IncomingWebhookEvent::RefundFailure, - transformers::RefundsAction::Paid => api::IncomingWebhookEvent::RefundSuccess, + transformers::RefundsAction::Failed => IncomingWebhookEvent::RefundFailure, + transformers::RefundsAction::Paid => IncomingWebhookEvent::RefundSuccess, transformers::RefundsAction::RefundSettled | transformers::RefundsAction::FundsReturned - | transformers::RefundsAction::Created => { - api::IncomingWebhookEvent::EventNotSupported - } + | transformers::RefundsAction::Created => IncomingWebhookEvent::EventNotSupported, }, transformers::WebhookAction::MandatesAction(action) => match action { transformers::MandatesAction::Active | transformers::MandatesAction::Reinstated => { - api::IncomingWebhookEvent::MandateActive + IncomingWebhookEvent::MandateActive } transformers::MandatesAction::Expired | transformers::MandatesAction::Cancelled | transformers::MandatesAction::Failed - | transformers::MandatesAction::Consumed => { - api::IncomingWebhookEvent::MandateRevoked - } + | transformers::MandatesAction::Consumed => IncomingWebhookEvent::MandateRevoked, transformers::MandatesAction::Created | transformers::MandatesAction::CustomerApprovalGranted | transformers::MandatesAction::CustomerApprovalSkipped @@ -861,9 +840,7 @@ impl api::IncomingWebhook for Gocardless { | transformers::MandatesAction::Submitted | transformers::MandatesAction::ResubmissionRequested | transformers::MandatesAction::Replaced - | transformers::MandatesAction::Blocked => { - api::IncomingWebhookEvent::EventNotSupported - } + | transformers::MandatesAction::Blocked => IncomingWebhookEvent::EventNotSupported, }, }; Ok(event_type) @@ -871,7 +848,7 @@ impl api::IncomingWebhook for Gocardless { fn get_webhook_resource_object( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let details: gocardless::GocardlessWebhookEvent = request .body diff --git a/crates/router/src/connector/gocardless/transformers.rs b/crates/hyperswitch_connectors/src/connectors/gocardless/transformers.rs similarity index 76% rename from crates/router/src/connector/gocardless/transformers.rs rename to crates/hyperswitch_connectors/src/connectors/gocardless/transformers.rs index c5c34574433d..25327358e7fe 100644 --- a/crates/router/src/connector/gocardless/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/gocardless/transformers.rs @@ -1,23 +1,29 @@ -use api_models::{ - enums::{CountryAlpha2, UsStatesAbbreviation}, - payments::AddressDetails, -}; +use api_models::enums::{CountryAlpha2, UsStatesAbbreviation}; +use common_enums::{AttemptStatus, Currency, RefundStatus}; use common_utils::{ id_type, pii::{self, IpAddress}, }; +use hyperswitch_domain_models::{ + payment_method_data::{BankDebitData, PaymentMethodData}, + router_data::{ConnectorAuthType, PaymentMethodToken, RouterData}, + router_flow_types::refunds::Execute, + router_request_types::{ + ConnectorCustomerData, PaymentMethodTokenizationData, PaymentsAuthorizeData, + PaymentsSyncData, ResponseId, SetupMandateRequestData, + }, + router_response_types::{MandateReference, PaymentsResponseData, RefundsResponseData}, + types, +}; +use hyperswitch_interfaces::{api, errors}; use masking::{ExposeInterface, Secret}; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{ - self, AddressDetailsData, BrowserInformationData, ConnectorCustomerData, - PaymentsAuthorizeRequestData, PaymentsSetupMandateRequestData, RouterData, - }, - core::errors, - types::{ - self, api, domain, storage::enums, transformers::ForeignTryFrom, MandateReference, - ResponseId, + types::{RefundsResponseRouterData, ResponseRouterData}, + utils::{ + self, AddressDetailsData, BrowserInformationData, CustomerData, ForeignTryFrom, + PaymentsAuthorizeRequestData, PaymentsSetupMandateRequestData, RouterData as _, }, }; @@ -26,10 +32,10 @@ pub struct GocardlessRouterData { pub router_data: T, } -impl TryFrom<(&api::CurrencyUnit, enums::Currency, i64, T)> for GocardlessRouterData { +impl TryFrom<(&api::CurrencyUnit, Currency, i64, T)> for GocardlessRouterData { type Error = error_stack::Report; fn try_from( - (_currency_unit, _currency, amount, item): (&api::CurrencyUnit, enums::Currency, i64, T), + (_currency_unit, _currency, amount, item): (&api::CurrencyUnit, Currency, i64, T), ) -> Result { Ok(Self { amount, @@ -105,7 +111,7 @@ impl TryFrom<&types::ConnectorCustomerRouterData> for GocardlessCustomerRequest } fn get_region( - address_details: &AddressDetails, + address_details: &hyperswitch_domain_models::address::AddressDetails, ) -> Result>, error_stack::Report> { match address_details.country { Some(CountryAlpha2::US) => { @@ -130,25 +136,25 @@ pub struct Customers { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, GocardlessCustomerResponse, - types::ConnectorCustomerData, - types::PaymentsResponseData, + ConnectorCustomerData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, GocardlessCustomerResponse, - types::ConnectorCustomerData, - types::PaymentsResponseData, + ConnectorCustomerData, + PaymentsResponseData, >, ) -> Result { Ok(Self { - response: Ok(types::PaymentsResponseData::ConnectorCustomerResponse { + response: Ok(PaymentsResponseData::ConnectorCustomerResponse { connector_customer_id: item.response.customers.id.expose(), }), ..item.data @@ -230,27 +236,27 @@ impl TryFrom<&types::TokenizationRouterData> for CustomerBankAccount { type Error = error_stack::Report; fn try_from(item: &types::TokenizationRouterData) -> Result { match &item.request.payment_method_data { - domain::PaymentMethodData::BankDebit(bank_debit_data) => { + PaymentMethodData::BankDebit(bank_debit_data) => { Self::try_from((bank_debit_data, item)) } - domain::PaymentMethodData::Card(_) - | domain::PaymentMethodData::CardRedirect(_) - | domain::PaymentMethodData::Wallet(_) - | domain::PaymentMethodData::PayLater(_) - | domain::PaymentMethodData::BankRedirect(_) - | domain::PaymentMethodData::BankTransfer(_) - | domain::PaymentMethodData::Crypto(_) - | domain::PaymentMethodData::MandatePayment - | domain::PaymentMethodData::Reward - | domain::PaymentMethodData::RealTimePayment(_) - | domain::PaymentMethodData::MobilePayment(_) - | domain::PaymentMethodData::Upi(_) - | domain::PaymentMethodData::Voucher(_) - | domain::PaymentMethodData::GiftCard(_) - | domain::PaymentMethodData::OpenBanking(_) - | domain::PaymentMethodData::CardToken(_) - | domain::PaymentMethodData::NetworkToken(_) - | domain::PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { + PaymentMethodData::Card(_) + | PaymentMethodData::CardRedirect(_) + | PaymentMethodData::Wallet(_) + | PaymentMethodData::PayLater(_) + | PaymentMethodData::BankRedirect(_) + | PaymentMethodData::BankTransfer(_) + | PaymentMethodData::Crypto(_) + | PaymentMethodData::MandatePayment + | PaymentMethodData::Reward + | PaymentMethodData::RealTimePayment(_) + | PaymentMethodData::MobilePayment(_) + | PaymentMethodData::Upi(_) + | PaymentMethodData::Voucher(_) + | PaymentMethodData::GiftCard(_) + | PaymentMethodData::OpenBanking(_) + | PaymentMethodData::CardToken(_) + | PaymentMethodData::NetworkToken(_) + | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("Gocardless"), ) @@ -260,13 +266,13 @@ impl TryFrom<&types::TokenizationRouterData> for CustomerBankAccount { } } -impl TryFrom<(&domain::BankDebitData, &types::TokenizationRouterData)> for CustomerBankAccount { +impl TryFrom<(&BankDebitData, &types::TokenizationRouterData)> for CustomerBankAccount { type Error = error_stack::Report; fn try_from( - (bank_debit_data, item): (&domain::BankDebitData, &types::TokenizationRouterData), + (bank_debit_data, item): (&BankDebitData, &types::TokenizationRouterData), ) -> Result { match bank_debit_data { - domain::BankDebitData::AchBankDebit { + BankDebitData::AchBankDebit { account_number, routing_number, bank_type, @@ -284,7 +290,7 @@ impl TryFrom<(&domain::BankDebitData, &types::TokenizationRouterData)> for Custo }; Ok(Self::USBankAccount(us_bank_account)) } - domain::BankDebitData::BecsBankDebit { + BankDebitData::BecsBankDebit { account_number, bsb_number, .. @@ -299,7 +305,7 @@ impl TryFrom<(&domain::BankDebitData, &types::TokenizationRouterData)> for Custo }; Ok(Self::AUBankAccount(au_bank_account)) } - domain::BankDebitData::SepaBankDebit { iban, .. } => { + BankDebitData::SepaBankDebit { iban, .. } => { let account_holder_name = item.get_billing_full_name()?; let international_bank_account = InternationalBankAccount { iban: iban.clone(), @@ -307,12 +313,10 @@ impl TryFrom<(&domain::BankDebitData, &types::TokenizationRouterData)> for Custo }; Ok(Self::InternationalBankAccount(international_bank_account)) } - domain::BankDebitData::BacsBankDebit { .. } => { - Err(errors::ConnectorError::NotImplemented( - utils::get_unimplemented_payment_method_error_message("Gocardless"), - ) - .into()) - } + BankDebitData::BacsBankDebit { .. } => Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("Gocardless"), + ) + .into()), } } } @@ -338,25 +342,25 @@ pub struct CustomerBankAccountResponse { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, GocardlessBankAccountResponse, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, + PaymentMethodTokenizationData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, GocardlessBankAccountResponse, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, + PaymentMethodTokenizationData, + PaymentsResponseData, >, ) -> Result { Ok(Self { - response: Ok(types::PaymentsResponseData::TokenizationResponse { + response: Ok(PaymentsResponseData::TokenizationResponse { token: item.response.customer_bank_accounts.id.expose(), }), ..item.data @@ -400,31 +404,31 @@ impl TryFrom<&types::SetupMandateRouterData> for GocardlessMandateRequest { type Error = error_stack::Report; fn try_from(item: &types::SetupMandateRouterData) -> Result { let (scheme, payer_ip_address) = match &item.request.payment_method_data { - domain::PaymentMethodData::BankDebit(bank_debit_data) => { + PaymentMethodData::BankDebit(bank_debit_data) => { let payer_ip_address = get_ip_if_required(bank_debit_data, item)?; Ok(( GocardlessScheme::try_from(bank_debit_data)?, payer_ip_address, )) } - domain::PaymentMethodData::Card(_) - | domain::PaymentMethodData::CardRedirect(_) - | domain::PaymentMethodData::Wallet(_) - | domain::PaymentMethodData::PayLater(_) - | domain::PaymentMethodData::BankRedirect(_) - | domain::PaymentMethodData::BankTransfer(_) - | domain::PaymentMethodData::Crypto(_) - | domain::PaymentMethodData::MandatePayment - | domain::PaymentMethodData::Reward - | domain::PaymentMethodData::RealTimePayment(_) - | domain::PaymentMethodData::MobilePayment(_) - | domain::PaymentMethodData::Upi(_) - | domain::PaymentMethodData::Voucher(_) - | domain::PaymentMethodData::GiftCard(_) - | domain::PaymentMethodData::OpenBanking(_) - | domain::PaymentMethodData::CardToken(_) - | domain::PaymentMethodData::NetworkToken(_) - | domain::PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { + PaymentMethodData::Card(_) + | PaymentMethodData::CardRedirect(_) + | PaymentMethodData::Wallet(_) + | PaymentMethodData::PayLater(_) + | PaymentMethodData::BankRedirect(_) + | PaymentMethodData::BankTransfer(_) + | PaymentMethodData::Crypto(_) + | PaymentMethodData::MandatePayment + | PaymentMethodData::Reward + | PaymentMethodData::RealTimePayment(_) + | PaymentMethodData::MobilePayment(_) + | PaymentMethodData::Upi(_) + | PaymentMethodData::Voucher(_) + | PaymentMethodData::GiftCard(_) + | PaymentMethodData::OpenBanking(_) + | PaymentMethodData::CardToken(_) + | PaymentMethodData::NetworkToken(_) + | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { Err(errors::ConnectorError::NotImplemented( "Setup Mandate flow for selected payment method through Gocardless".to_string(), )) @@ -432,9 +436,8 @@ impl TryFrom<&types::SetupMandateRouterData> for GocardlessMandateRequest { }?; let payment_method_token = item.get_payment_method_token()?; let customer_bank_account = match payment_method_token { - types::PaymentMethodToken::Token(token) => Ok(token), - types::PaymentMethodToken::ApplePayDecrypt(_) - | types::PaymentMethodToken::PazeDecrypt(_) => { + PaymentMethodToken::Token(token) => Ok(token), + PaymentMethodToken::ApplePayDecrypt(_) | PaymentMethodToken::PazeDecrypt(_) => { Err(errors::ConnectorError::NotImplemented( "Setup Mandate flow for selected payment method through Gocardless".to_string(), )) @@ -456,31 +459,29 @@ impl TryFrom<&types::SetupMandateRouterData> for GocardlessMandateRequest { } fn get_ip_if_required( - bank_debit_data: &domain::BankDebitData, + bank_debit_data: &BankDebitData, item: &types::SetupMandateRouterData, ) -> Result>, error_stack::Report> { let ip_address = item.request.get_browser_info()?.get_ip_address()?; match bank_debit_data { - domain::BankDebitData::AchBankDebit { .. } => Ok(Some(ip_address)), - domain::BankDebitData::SepaBankDebit { .. } - | domain::BankDebitData::BecsBankDebit { .. } - | domain::BankDebitData::BacsBankDebit { .. } => Ok(None), + BankDebitData::AchBankDebit { .. } => Ok(Some(ip_address)), + BankDebitData::SepaBankDebit { .. } + | BankDebitData::BecsBankDebit { .. } + | BankDebitData::BacsBankDebit { .. } => Ok(None), } } -impl TryFrom<&domain::BankDebitData> for GocardlessScheme { +impl TryFrom<&BankDebitData> for GocardlessScheme { type Error = error_stack::Report; - fn try_from(item: &domain::BankDebitData) -> Result { + fn try_from(item: &BankDebitData) -> Result { match item { - domain::BankDebitData::AchBankDebit { .. } => Ok(Self::Ach), - domain::BankDebitData::SepaBankDebit { .. } => Ok(Self::SepaCore), - domain::BankDebitData::BecsBankDebit { .. } => Ok(Self::Becs), - domain::BankDebitData::BacsBankDebit { .. } => { - Err(errors::ConnectorError::NotImplemented( - "Setup Mandate flow for selected payment method through Gocardless".to_string(), - ) - .into()) - } + BankDebitData::AchBankDebit { .. } => Ok(Self::Ach), + BankDebitData::SepaBankDebit { .. } => Ok(Self::SepaCore), + BankDebitData::BecsBankDebit { .. } => Ok(Self::Becs), + BankDebitData::BacsBankDebit { .. } => Err(errors::ConnectorError::NotImplemented( + "Setup Mandate flow for selected payment method through Gocardless".to_string(), + ) + .into()), } } } @@ -497,21 +498,21 @@ pub struct MandateResponse { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, GocardlessMandateResponse, - types::SetupMandateRequestData, - types::PaymentsResponseData, + SetupMandateRequestData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, GocardlessMandateResponse, - types::SetupMandateRequestData, - types::PaymentsResponseData, + SetupMandateRequestData, + PaymentsResponseData, >, ) -> Result { let mandate_reference = Some(MandateReference { @@ -521,7 +522,7 @@ impl connector_mandate_request_reference_id: None, }); Ok(Self { - response: Ok(types::PaymentsResponseData::TransactionResponse { + response: Ok(PaymentsResponseData::TransactionResponse { connector_metadata: None, connector_response_reference_id: None, incremental_authorization_allowed: None, @@ -531,7 +532,7 @@ impl network_txn_id: None, charge_id: None, }), - status: enums::AttemptStatus::Charged, + status: AttemptStatus::Charged, ..item.data }) } @@ -545,7 +546,7 @@ pub struct GocardlessPaymentsRequest { #[derive(Debug, Serialize)] pub struct GocardlessPayment { amount: i64, - currency: enums::Currency, + currency: Currency, description: Option, metadata: PaymentMetaData, links: PaymentLink, @@ -599,11 +600,11 @@ pub struct GocardlessAuthType { pub(super) access_token: Secret, } -impl TryFrom<&types::ConnectorAuthType> for GocardlessAuthType { +impl TryFrom<&ConnectorAuthType> for GocardlessAuthType { type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + fn try_from(auth_type: &ConnectorAuthType) -> Result { match auth_type { - types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self { + ConnectorAuthType::HeaderKey { api_key } => Ok(Self { access_token: api_key.to_owned(), }), _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), @@ -624,7 +625,7 @@ pub enum GocardlessPaymentStatus { Failed, } -impl From for enums::AttemptStatus { +impl From for AttemptStatus { fn from(item: GocardlessPaymentStatus) -> Self { match item { GocardlessPaymentStatus::PendingCustomerApproval @@ -651,21 +652,21 @@ pub struct PaymentResponse { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, GocardlessPaymentsResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, + PaymentsAuthorizeData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, GocardlessPaymentsResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, + PaymentsAuthorizeData, + PaymentsResponseData, >, ) -> Result { let mandate_reference = MandateReference { @@ -675,8 +676,8 @@ impl connector_mandate_request_reference_id: None, }; Ok(Self { - status: enums::AttemptStatus::from(item.response.payments.status), - response: Ok(types::PaymentsResponseData::TransactionResponse { + status: AttemptStatus::from(item.response.payments.status), + response: Ok(PaymentsResponseData::TransactionResponse { resource_id: ResponseId::ConnectorTransactionId(item.response.payments.id), redirection_data: Box::new(None), mandate_reference: Box::new(Some(mandate_reference)), @@ -693,26 +694,21 @@ impl impl TryFrom< - types::ResponseRouterData< - F, - GocardlessPaymentsResponse, - types::PaymentsSyncData, - types::PaymentsResponseData, - >, - > for types::RouterData + ResponseRouterData, + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, GocardlessPaymentsResponse, - types::PaymentsSyncData, - types::PaymentsResponseData, + PaymentsSyncData, + PaymentsResponseData, >, ) -> Result { Ok(Self { - status: enums::AttemptStatus::from(item.response.payments.status), - response: Ok(types::PaymentsResponseData::TransactionResponse { + status: AttemptStatus::from(item.response.payments.status), + response: Ok(PaymentsResponseData::TransactionResponse { resource_id: ResponseId::ConnectorTransactionId(item.response.payments.id), redirection_data: Box::new(None), mandate_reference: Box::new(None), @@ -774,17 +770,17 @@ pub struct RefundResponse { id: String, } -impl TryFrom> - for types::RefundsRouterData +impl TryFrom> + for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id: item.response.id.to_string(), - refund_status: enums::RefundStatus::Pending, + refund_status: RefundStatus::Pending, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs index cef3d684e7b0..bbfa0598cfa1 100644 --- a/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/mollie/transformers.rs @@ -354,7 +354,7 @@ fn get_billing_details( } fn get_address_details( - address: Option<&api_models::payments::AddressDetails>, + address: Option<&hyperswitch_domain_models::address::AddressDetails>, ) -> Result, Error> { let address_details = match address { Some(address) => { diff --git a/crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs index 180db6268646..479abf13b13a 100644 --- a/crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs @@ -916,7 +916,6 @@ pub struct Data { } #[derive(Default, Debug, Clone, Serialize, Deserialize, Eq, PartialEq)] - pub struct MultisafepayPaymentDetails { pub account_holder_name: Option>, pub account_id: Option>, diff --git a/crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs index 6297b97ee98a..8d6dc42926ba 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs @@ -122,7 +122,6 @@ pub struct NexinetsBankRedirects { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] - pub struct NexinetsAsyncDetails { pub success_url: Option, pub cancel_url: Option, diff --git a/crates/hyperswitch_connectors/src/connectors/nexixpay.rs b/crates/hyperswitch_connectors/src/connectors/nexixpay.rs index 76085324167e..701a0a54e4b4 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexixpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexixpay.rs @@ -1,4 +1,5 @@ pub mod transformers; +use std::collections::HashSet; use common_enums::enums; use common_utils::{ @@ -9,6 +10,7 @@ use common_utils::{ }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ + payment_method_data::PaymentMethodData, router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData}, router_flow_types::{ access_token_auth::AccessTokenAuth, @@ -46,7 +48,7 @@ use uuid::Uuid; use crate::{ constants::headers, types::ResponseRouterData, - utils::{self, RefundsRequestData}, + utils::{self, PaymentMethodDataType, RefundsRequestData}, }; #[derive(Clone)] @@ -212,6 +214,15 @@ impl ConnectorValidation for Nexixpay { ), } } + fn validate_mandate_payment( + &self, + pm_type: Option, + pm_data: PaymentMethodData, + ) -> CustomResult<(), errors::ConnectorError> { + let mandate_supported_pmd: HashSet = + HashSet::from([PaymentMethodDataType::Card]); + utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id()) + } } impl ConnectorIntegration for Nexixpay {} @@ -415,10 +426,14 @@ impl ConnectorIntegration CustomResult { - Ok(format!("{}/orders/3steps/init", self.base_url(connectors))) + if req.request.off_session == Some(true) { + Ok(format!("{}/orders/mit", self.base_url(connectors))) + } else { + Ok(format!("{}/orders/3steps/init", self.base_url(connectors))) + } } fn get_request_body( diff --git a/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs index b1e9c3015e8b..9c35b913db72 100644 --- a/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs @@ -14,7 +14,9 @@ use hyperswitch_domain_models::{ CompleteAuthorizeData, PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSyncData, ResponseId, }, - router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData}, + router_response_types::{ + MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData, + }, types::{ PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData, PaymentsCompleteAuthorizeRouterData, PaymentsPreProcessingRouterData, RefundsRouterData, @@ -47,11 +49,58 @@ impl From<(StringMinorUnit, T)> for NexixpayRouterData { } } +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum NexixpayRecurringAction { + NoRecurring, + SubsequentPayment, + ContractCreation, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum ContractType { + MitUnscheduled, + MitScheduled, + Cit, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RecurrenceRequest { + action: NexixpayRecurringAction, + contract_id: Secret, + contract_type: ContractType, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NexixpayNonMandatePaymentRequest { + card: NexixpayCard, + recurrence: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NexixpayMandatePaymentRequest { + contract_id: Secret, + capture_type: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum NexixpayPaymentsRequestData { + NexixpayNonMandatePaymentRequest(Box), + NexixpayMandatePaymentRequest(Box), +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NexixpayPaymentsRequest { order: Order, - card: NexixpayCard, + #[serde(flatten)] + payment_data: NexixpayPaymentsRequestData, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -69,6 +118,7 @@ pub struct NexixpayCompleteAuthorizeRequest { operation_id: String, capture_type: Option, three_d_s_auth_data: ThreeDSAuthData, + recurrence: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -108,13 +158,13 @@ pub struct Order { #[serde(rename_all = "camelCase")] pub struct CustomerInfo { card_holder_name: Secret, - billing_address: Address, - shipping_address: Option

, + billing_address: BillingAddress, + shipping_address: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct Address { +pub struct BillingAddress { name: Secret, street: Secret, city: String, @@ -122,6 +172,16 @@ pub struct Address { country: enums::CountryAlpha2, } +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ShippingAddress { + name: Option>, + street: Option>, + city: Option, + post_code: Option>, + country: Option, +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct NexixpayCard { @@ -137,12 +197,26 @@ struct Recurrence { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct NexixpayPaymentsResponse { +pub struct PaymentsResponse { operation: Operation, three_d_s_auth_request: String, three_d_s_auth_url: Secret, } +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct NexixpayMandateResponse { + operation: Operation, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(untagged)] +pub enum NexixpayPaymentsResponse { + PaymentResponse(Box), + MandateResponse(Box), +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ThreeDSAuthResult { @@ -371,54 +445,158 @@ impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaym fn try_from( item: &NexixpayRouterData<&PaymentsAuthorizeRouterData>, ) -> Result { - match item.router_data.request.payment_method_data { - PaymentMethodData::Card(ref req_card) => { - let card = NexixpayCard { - pan: req_card.card_number.clone(), - expiry_date: req_card.get_expiry_date_as_mmyy()?, - }; - let billing_address = Address { - name: item.router_data.get_billing_full_name()?, - street: item.router_data.get_billing_line1()?, - city: item.router_data.get_billing_city()?, - post_code: item.router_data.get_billing_zip()?, - country: item.router_data.get_billing_country()?, - }; - let customer_info = CustomerInfo { - card_holder_name: item.router_data.get_billing_full_name()?, - billing_address: billing_address.clone(), - shipping_address: Some(billing_address), - }; - let order = Order { - order_id: item.router_data.connector_request_reference_id.clone(), - amount: item.amount.clone(), - currency: item.router_data.request.currency, - description: item.router_data.description.clone(), - customer_info, + let billing_address_street = format!( + "{}, {}", + item.router_data.get_billing_line1()?.expose(), + item.router_data.get_billing_line2()?.expose() + ); + + let billing_address = BillingAddress { + name: item.router_data.get_billing_full_name()?, + street: Secret::new(billing_address_street), + city: item.router_data.get_billing_city()?, + post_code: item.router_data.get_billing_zip()?, + country: item.router_data.get_billing_country()?, + }; + let shipping_address_street = match ( + item.router_data.get_optional_shipping_line1(), + item.router_data.get_optional_shipping_line2(), + ) { + (Some(line1), Some(line2)) => Some(Secret::new(format!( + "{}, {}", + line1.expose(), + line2.expose() + ))), + (Some(line1), None) => Some(Secret::new(line1.expose())), + (None, Some(line2)) => Some(Secret::new(line2.expose())), + (None, None) => None, + }; + + let shipping_address = item + .router_data + .get_optional_billing() + .map(|_| ShippingAddress { + name: item.router_data.get_optional_shipping_full_name(), + street: shipping_address_street, + city: item.router_data.get_optional_shipping_city(), + post_code: item.router_data.get_optional_shipping_zip(), + country: item.router_data.get_optional_shipping_country(), + }); + let customer_info = CustomerInfo { + card_holder_name: item.router_data.get_billing_full_name()?, + billing_address: billing_address.clone(), + shipping_address: shipping_address.clone(), + }; + let order = Order { + order_id: item.router_data.connector_request_reference_id.clone(), + amount: item.amount.clone(), + currency: item.router_data.request.currency, + description: item.router_data.description.clone(), + customer_info, + }; + let payment_data = NexixpayPaymentsRequestData::try_from(item)?; + Ok(Self { + order, + payment_data, + }) + } +} + +impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaymentsRequestData { + type Error = error_stack::Report; + fn try_from( + item: &NexixpayRouterData<&PaymentsAuthorizeRouterData>, + ) -> Result { + match item + .router_data + .request + .mandate_id + .clone() + .and_then(|mandate_id| mandate_id.mandate_reference_id) + { + None => { + let recurrence_request_obj = if item.router_data.request.is_mandate_payment() { + let contract_id = item + .router_data + .connector_mandate_request_reference_id + .clone() + .ok_or_else(|| errors::ConnectorError::MissingRequiredField { + field_name: "connector_mandate_request_reference_id", + })?; + Some(RecurrenceRequest { + action: NexixpayRecurringAction::ContractCreation, + contract_id: Secret::new(contract_id), + contract_type: ContractType::MitUnscheduled, + }) + } else { + None }; - Ok(Self { order, card }) + + match item.router_data.request.payment_method_data { + PaymentMethodData::Card(ref req_card) => { + if item.router_data.is_three_ds() { + Ok(Self::NexixpayNonMandatePaymentRequest(Box::new( + NexixpayNonMandatePaymentRequest { + card: NexixpayCard { + pan: req_card.card_number.clone(), + expiry_date: req_card.get_expiry_date_as_mmyy()?, + }, + recurrence: recurrence_request_obj, + }, + ))) + } else { + Err(errors::ConnectorError::NotSupported { + message: "No threeds is not supported".to_string(), + connector: "nexixpay", + } + .into()) + } + } + PaymentMethodData::CardRedirect(_) + | PaymentMethodData::Wallet(_) + | PaymentMethodData::PayLater(_) + | PaymentMethodData::BankRedirect(_) + | PaymentMethodData::BankDebit(_) + | PaymentMethodData::BankTransfer(_) + | PaymentMethodData::Crypto(_) + | PaymentMethodData::MandatePayment + | PaymentMethodData::Reward + | PaymentMethodData::RealTimePayment(_) + | PaymentMethodData::Upi(_) + | PaymentMethodData::MobilePayment(_) + | PaymentMethodData::Voucher(_) + | PaymentMethodData::GiftCard(_) + | PaymentMethodData::OpenBanking(_) + | PaymentMethodData::CardToken(_) + | PaymentMethodData::CardDetailsForNetworkTransactionId(_) + | PaymentMethodData::NetworkToken(_) => { + Err(errors::ConnectorError::NotImplemented( + get_unimplemented_payment_method_error_message("nexixpay"), + ))? + } + } } - PaymentMethodData::CardRedirect(_) - | PaymentMethodData::Wallet(_) - | PaymentMethodData::PayLater(_) - | PaymentMethodData::BankRedirect(_) - | PaymentMethodData::BankDebit(_) - | PaymentMethodData::BankTransfer(_) - | PaymentMethodData::Crypto(_) - | PaymentMethodData::MandatePayment - | PaymentMethodData::Reward - | PaymentMethodData::RealTimePayment(_) - | PaymentMethodData::MobilePayment(_) - | PaymentMethodData::Upi(_) - | PaymentMethodData::Voucher(_) - | PaymentMethodData::GiftCard(_) - | PaymentMethodData::OpenBanking(_) - | PaymentMethodData::CardToken(_) - | PaymentMethodData::NetworkToken(_) - | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => { + Some(api_models::payments::MandateReferenceId::ConnectorMandateId(mandate_data)) => { + let contract_id = Secret::new( + mandate_data + .get_connector_mandate_request_reference_id() + .ok_or(errors::ConnectorError::MissingConnectorMandateID)?, + ); + let capture_type = + get_nexixpay_capture_type(item.router_data.request.capture_method)?; + Ok(Self::NexixpayMandatePaymentRequest(Box::new( + NexixpayMandatePaymentRequest { + contract_id, + capture_type, + }, + ))) + } + Some(api_models::payments::MandateReferenceId::NetworkTokenWithNTI(_)) + | Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => { Err(errors::ConnectorError::NotImplemented( get_unimplemented_payment_method_error_message("nexixpay"), - ))? + ) + .into()) } } } @@ -598,45 +776,81 @@ impl PaymentsResponseData, >, ) -> Result { - let complete_authorize_url = item.data.request.get_complete_authorize_url()?; - let operation_id: String = item.response.operation.operation_id; - let redirection_form = nexixpay_threeds_link(NexixpayRedirectionRequest { - three_d_s_auth_url: item.response.three_d_s_auth_url.expose().to_string(), - three_ds_request: item.response.three_d_s_auth_request.clone(), - return_url: complete_authorize_url.clone(), - transaction_id: operation_id.clone(), - })?; - let is_auto_capture = item.data.request.is_auto_capture()?; - let connector_metadata = Some(serde_json::json!(NexixpayConnectorMetaData { - three_d_s_auth_result: None, - three_d_s_auth_response: None, - authorization_operation_id: Some(operation_id.clone()), - cancel_operation_id: None, - capture_operation_id: { - if is_auto_capture { - Some(operation_id) - } else { - None - } - }, - psync_flow: NexixpayPaymentIntent::Authorize - })); - Ok(Self { - status: AttemptStatus::from(item.response.operation.operation_result), - response: Ok(PaymentsResponseData::TransactionResponse { - resource_id: ResponseId::ConnectorTransactionId( - item.response.operation.order_id.clone(), - ), - redirection_data: Box::new(Some(redirection_form.clone())), - mandate_reference: Box::new(None), - connector_metadata, - network_txn_id: None, - connector_response_reference_id: Some(item.response.operation.order_id), - incremental_authorization_allowed: None, - charge_id: None, + match item.response { + NexixpayPaymentsResponse::PaymentResponse(ref response_body) => { + let complete_authorize_url = item.data.request.get_complete_authorize_url()?; + let operation_id: String = response_body.operation.operation_id.clone(); + let redirection_form = nexixpay_threeds_link(NexixpayRedirectionRequest { + three_d_s_auth_url: response_body + .three_d_s_auth_url + .clone() + .expose() + .to_string(), + three_ds_request: response_body.three_d_s_auth_request.clone(), + return_url: complete_authorize_url.clone(), + transaction_id: operation_id.clone(), + })?; + let is_auto_capture = item.data.request.is_auto_capture()?; + let connector_metadata = Some(serde_json::json!(NexixpayConnectorMetaData { + three_d_s_auth_result: None, + three_d_s_auth_response: None, + authorization_operation_id: Some(operation_id.clone()), + cancel_operation_id: None, + capture_operation_id: { + if is_auto_capture { + Some(operation_id) + } else { + None + } + }, + psync_flow: NexixpayPaymentIntent::Authorize + })); + Ok(Self { + status: AttemptStatus::from(response_body.operation.operation_result.clone()), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId( + response_body.operation.order_id.clone(), + ), + redirection_data: Box::new(Some(redirection_form.clone())), + mandate_reference: Box::new(Some(MandateReference { + connector_mandate_id: item + .data + .connector_mandate_request_reference_id + .clone(), + payment_method_id: None, + mandate_metadata: None, + connector_mandate_request_reference_id: None, + })), + connector_metadata, + network_txn_id: None, + connector_response_reference_id: Some( + response_body.operation.order_id.clone(), + ), + incremental_authorization_allowed: None, + charge_id: None, + }), + ..item.data + }) + } + NexixpayPaymentsResponse::MandateResponse(ref mandate_response) => Ok(Self { + status: AttemptStatus::from(mandate_response.operation.operation_result.clone()), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId( + mandate_response.operation.order_id.clone(), + ), + redirection_data: Box::new(None), + mandate_reference: Box::new(None), + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: Some( + mandate_response.operation.order_id.clone(), + ), + incremental_authorization_allowed: None, + charge_id: None, + }), + ..item.data }), - ..item.data - }) + } } } @@ -738,7 +952,6 @@ impl meta_data, is_auto_capture, })?); - Ok(Self { status: AttemptStatus::from(item.response.operation.operation_result), response: Ok(PaymentsResponseData::TransactionResponse { @@ -746,7 +959,12 @@ impl item.response.operation.order_id.clone(), ), redirection_data: Box::new(None), - mandate_reference: Box::new(None), + mandate_reference: Box::new(Some(MandateReference { + connector_mandate_id: item.data.connector_mandate_request_reference_id.clone(), + payment_method_id: None, + mandate_metadata: None, + connector_mandate_request_reference_id: None, + })), connector_metadata, network_txn_id: None, connector_response_reference_id: Some(item.response.operation.order_id), @@ -775,17 +993,47 @@ impl TryFrom<&NexixpayRouterData<&PaymentsCompleteAuthorizeRouterData>> let order_id = item.router_data.connector_request_reference_id.clone(); let amount = item.amount.clone(); - let billing_address = Address { + let billing_address_street = format!( + "{}, {}", + item.router_data.get_billing_line1()?.expose(), + item.router_data.get_billing_line2()?.expose() + ); + + let billing_address = BillingAddress { name: item.router_data.get_billing_full_name()?, - street: item.router_data.get_billing_line1()?, + street: Secret::new(billing_address_street), city: item.router_data.get_billing_city()?, post_code: item.router_data.get_billing_zip()?, country: item.router_data.get_billing_country()?, }; + let shipping_address_street = match ( + item.router_data.get_optional_shipping_line1(), + item.router_data.get_optional_shipping_line2(), + ) { + (Some(line1), Some(line2)) => Some(Secret::new(format!( + "{}, {}", + line1.expose(), + line2.expose() + ))), + (Some(line1), None) => Some(Secret::new(line1.expose())), + (None, Some(line2)) => Some(Secret::new(line2.expose())), + (None, None) => None, + }; + + let shipping_address = item + .router_data + .get_optional_billing() + .map(|_| ShippingAddress { + name: item.router_data.get_optional_shipping_full_name(), + street: shipping_address_street, + city: item.router_data.get_optional_shipping_city(), + post_code: item.router_data.get_optional_shipping_zip(), + country: item.router_data.get_optional_shipping_country(), + }); let customer_info = CustomerInfo { card_holder_name: item.router_data.get_billing_full_name()?, billing_address: billing_address.clone(), - shipping_address: Some(billing_address), + shipping_address: shipping_address.clone(), }; let order_data = Order { order_id, @@ -841,12 +1089,25 @@ impl TryFrom<&NexixpayRouterData<&PaymentsCompleteAuthorizeRouterData>> .into()) } }; + let contract_id = Secret::new( + item.router_data + .connector_mandate_request_reference_id + .clone() + .ok_or_else(|| errors::ConnectorError::MissingRequiredField { + field_name: "connector_mandate_request_reference_id", + })?, + ); Ok(Self { order: order_data, card: card?, operation_id, capture_type, three_d_s_auth_data, + recurrence: Some(RecurrenceRequest { + action: NexixpayRecurringAction::ContractCreation, + contract_id, + contract_type: ContractType::MitUnscheduled, + }), }) } } @@ -870,7 +1131,12 @@ impl response: Ok(PaymentsResponseData::TransactionResponse { resource_id: ResponseId::ConnectorTransactionId(item.response.order_id.clone()), redirection_data: Box::new(None), - mandate_reference: Box::new(None), + mandate_reference: Box::new(Some(MandateReference { + connector_mandate_id: item.data.connector_mandate_request_reference_id.clone(), + payment_method_id: None, + mandate_metadata: None, + connector_mandate_request_reference_id: None, + })), connector_metadata: item.data.request.connector_meta.clone(), network_txn_id: None, connector_response_reference_id: Some(item.response.order_id.clone()), diff --git a/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs b/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs index b2bf76944c0f..18783c64a016 100644 --- a/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/novalnet/transformers.rs @@ -80,7 +80,6 @@ pub struct NovalnetPaymentsRequestCustomer { no_nc: i64, } #[derive(Default, Debug, Clone, Serialize, Deserialize)] - pub struct NovalnetCard { card_number: CardNumber, card_expiry_month: Secret, diff --git a/crates/router/src/connector/prophetpay.rs b/crates/hyperswitch_connectors/src/connectors/prophetpay.rs similarity index 69% rename from crates/router/src/connector/prophetpay.rs rename to crates/hyperswitch_connectors/src/connectors/prophetpay.rs index ef49e716d9a8..b6e16fc23579 100644 --- a/crates/router/src/connector/prophetpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/prophetpay.rs @@ -2,30 +2,47 @@ pub mod transformers; use std::fmt::Debug; +use api_models::webhooks::{IncomingWebhookEvent, ObjectReferenceId}; use base64::Engine; -use common_utils::request::RequestContent; +use common_utils::{ + consts::BASE64_ENGINE, + errors::CustomResult, + ext_traits::BytesExt, + request::{Method, Request, RequestBuilder, RequestContent}, +}; use error_stack::{report, ResultExt}; -use masking::PeekInterface; -use transformers as prophetpay; - -use crate::{ - configs::settings, - consts, - core::errors::{self, CustomResult}, - events::connector_api_logs::ConnectorEvent, - headers, - services::{ - self, - request::{self, Mask}, - ConnectorIntegration, ConnectorValidation, +use hyperswitch_domain_models::{ + router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData}, + router_flow_types::{ + access_token_auth::AccessTokenAuth, + payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, + refunds::{Execute, RSync}, + CompleteAuthorize, + }, + router_request_types::{ + AccessTokenRequestData, CompleteAuthorizeData, PaymentMethodTokenizationData, + PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, + PaymentsSyncData, RefundsData, SetupMandateRequestData, }, + router_response_types::{PaymentsResponseData, RefundsResponseData}, types::{ - self, - api::{self, ConnectorCommon, ConnectorCommonExt}, - ErrorResponse, Response, + PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCompleteAuthorizeRouterData, + PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData, }, - utils::BytesExt, }; +use hyperswitch_interfaces::{ + api::{self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorValidation}, + configs::Connectors, + consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE}, + errors, + events::connector_api_logs::ConnectorEvent, + types::{self, Response}, + webhooks::{IncomingWebhook, IncomingWebhookRequestDetails}, +}; +use masking::{Mask, PeekInterface}; +use transformers as prophetpay; + +use crate::{constants::headers, types::ResponseRouterData}; #[derive(Debug, Clone)] pub struct Prophetpay; @@ -43,12 +60,8 @@ impl api::RefundSync for Prophetpay {} impl api::PaymentToken for Prophetpay {} impl api::payments::PaymentsCompleteAuthorize for Prophetpay {} -impl - ConnectorIntegration< - api::PaymentMethodToken, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, - > for Prophetpay +impl ConnectorIntegration + for Prophetpay { // Not Implemented (R) } @@ -59,9 +72,9 @@ where { fn build_headers( &self, - req: &types::RouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { let mut header = vec![( headers::CONTENT_TYPE.to_string(), self.get_content_type().to_string().into(), @@ -85,19 +98,19 @@ impl ConnectorCommon for Prophetpay { "application/json" } - fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { connectors.prophetpay.base_url.as_ref() } fn get_auth_header( &self, - auth_type: &types::ConnectorAuthType, - ) -> CustomResult)>, errors::ConnectorError> { + auth_type: &ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { let auth = prophetpay::ProphetpayAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; let auth_val = format!("{}:{}", auth.user_name.peek(), auth.password.peek()); - let basic_token = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_val)); + let basic_token = format!("Basic {}", BASE64_ENGINE.encode(auth_val)); Ok(vec![( headers::AUTHORIZATION.to_string(), @@ -120,8 +133,8 @@ impl ConnectorCommon for Prophetpay { Ok(ErrorResponse { status_code: res.status_code, - code: consts::NO_ERROR_CODE.to_string(), - message: consts::NO_ERROR_MESSAGE.to_string(), + code: NO_ERROR_CODE.to_string(), + message: NO_ERROR_MESSAGE.to_string(), reason: Some(response.to_string()), attempt_status: None, connector_transaction_id: None, @@ -133,33 +146,20 @@ impl ConnectorValidation for Prophetpay { //TODO: implement functions when support enabled } -impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { //TODO: implement sessions flow } -impl ConnectorIntegration - for Prophetpay -{ -} +impl ConnectorIntegration for Prophetpay {} -impl - ConnectorIntegration< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - > for Prophetpay +impl ConnectorIntegration + for Prophetpay { fn build_request( &self, - _req: &types::RouterData< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - >, - _connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + _req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Err( errors::ConnectorError::NotImplemented("Setup Mandate flow for Prophetpay".to_string()) .into(), @@ -167,14 +167,12 @@ impl } } -impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { fn get_headers( &self, - req: &types::PaymentsAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -184,8 +182,8 @@ impl ConnectorIntegration CustomResult { Ok(format!( "{}hp/api/HostedTokenize/CreateHostedTokenize", @@ -195,8 +193,8 @@ impl ConnectorIntegration CustomResult { let connector_router_data = prophetpay::ProphetpayRouterData::try_from(( &self.get_currency_unit(), @@ -211,12 +209,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsAuthorizeType::get_url( self, req, connectors, )?) @@ -233,12 +231,12 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult + ) -> CustomResult where - types::PaymentsResponseData: Clone, + PaymentsResponseData: Clone, { let response: prophetpay::ProphetpayTokenResponse = res .response @@ -248,7 +246,7 @@ impl ConnectorIntegration for Prophetpay +impl ConnectorIntegration + for Prophetpay { fn get_headers( &self, - req: &types::PaymentsCompleteAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsCompleteAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -285,8 +279,8 @@ impl fn get_url( &self, - _req: &types::PaymentsCompleteAuthorizeRouterData, - connectors: &settings::Connectors, + _req: &PaymentsCompleteAuthorizeRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!( "{}hp/api/Transactions/ProcessTransaction", @@ -296,8 +290,8 @@ impl fn get_request_body( &self, - req: &types::PaymentsCompleteAuthorizeRouterData, - _connectors: &settings::Connectors, + req: &PaymentsCompleteAuthorizeRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_router_data = prophetpay::ProphetpayRouterData::try_from(( &self.get_currency_unit(), @@ -313,12 +307,12 @@ impl fn build_request( &self, - req: &types::PaymentsCompleteAuthorizeRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &PaymentsCompleteAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsCompleteAuthorizeType::get_url( self, req, connectors, )?) @@ -335,12 +329,12 @@ impl fn handle_response( &self, - data: &types::PaymentsCompleteAuthorizeRouterData, + data: &PaymentsCompleteAuthorizeRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult + ) -> CustomResult where - types::PaymentsResponseData: Clone, + PaymentsResponseData: Clone, { let response: prophetpay::ProphetpayCompleteAuthResponse = res .response @@ -350,7 +344,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -366,14 +360,12 @@ impl } } -impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { fn get_headers( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -383,8 +375,8 @@ impl ConnectorIntegration CustomResult { Ok(format!( "{}hp/api/Transactions/ProcessTransaction", @@ -394,8 +386,8 @@ impl ConnectorIntegration CustomResult { let connector_req = prophetpay::ProphetpaySyncRequest::try_from(req)?; @@ -404,12 +396,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) @@ -422,10 +414,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: prophetpay::ProphetpaySyncResponse = res .response .parse_struct("prophetpay PaymentsSyncResponse") @@ -434,7 +426,7 @@ impl ConnectorIntegration - for Prophetpay -{ -} +impl ConnectorIntegration for Prophetpay {} // This is Void Implementation for Prophetpay // Since Prophetpay does not have capture this have been commented out but kept if it is required for future usage -impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { /* fn get_headers( &self, @@ -497,9 +484,9 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + _req: &PaymentsCancelRouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Err(errors::ConnectorError::NotImplemented("Void flow not implemented".to_string()).into()) } @@ -530,14 +517,12 @@ impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { fn get_headers( &self, - req: &types::RefundsRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -547,8 +532,8 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, + _req: &RefundsRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!( "{}hp/api/Transactions/ProcessTransaction", @@ -558,8 +543,8 @@ impl ConnectorIntegration, - _connectors: &settings::Connectors, + req: &RefundsRouterData, + _connectors: &Connectors, ) -> CustomResult { let connector_router_data = prophetpay::ProphetpayRouterData::try_from(( &self.get_currency_unit(), @@ -573,11 +558,11 @@ impl ConnectorIntegration, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { - let request = services::RequestBuilder::new() - .method(services::Method::Post) + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::RefundExecuteType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundExecuteType::get_headers( @@ -592,10 +577,10 @@ impl ConnectorIntegration, + data: &RefundsRouterData, event_builder: Option<&mut ConnectorEvent>, res: Response, - ) -> CustomResult, errors::ConnectorError> { + ) -> CustomResult, errors::ConnectorError> { let response: prophetpay::ProphetpayRefundResponse = res .response .parse_struct("prophetpay ProphetpayRefundResponse") @@ -604,7 +589,7 @@ impl ConnectorIntegration - for Prophetpay -{ +impl ConnectorIntegration for Prophetpay { fn get_headers( &self, - req: &types::RefundSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) } @@ -637,8 +620,8 @@ impl ConnectorIntegration CustomResult { Ok(format!( "{}hp/api/Transactions/ProcessTransaction", @@ -648,8 +631,8 @@ impl ConnectorIntegration CustomResult { let connector_req = prophetpay::ProphetpayRefundSyncRequest::try_from(req)?; @@ -658,12 +641,12 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Ok(Some( - services::RequestBuilder::new() - .method(services::Method::Post) + RequestBuilder::new() + .method(Method::Post) .url(&types::RefundSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::RefundSyncType::get_headers(self, req, connectors)?) @@ -676,10 +659,10 @@ impl ConnectorIntegration, res: Response, - ) -> CustomResult { + ) -> CustomResult { let response: prophetpay::ProphetpayRefundSyncResponse = res .response .parse_struct("prophetpay ProphetpayRefundResponse") @@ -688,7 +671,7 @@ impl ConnectorIntegration, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_event_type( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + _request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } fn get_webhook_resource_object( &self, - _request: &api::IncomingWebhookRequestDetails<'_>, + _request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { Err(report!(errors::ConnectorError::WebhooksNotImplemented)) } diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/prophetpay/transformers.rs similarity index 83% rename from crates/router/src/connector/prophetpay/transformers.rs rename to crates/hyperswitch_connectors/src/connectors/prophetpay/transformers.rs index 24bd4642c019..53f902ff4956 100644 --- a/crates/router/src/connector/prophetpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/prophetpay/transformers.rs @@ -1,17 +1,30 @@ use std::collections::HashMap; -use common_utils::{consts, errors::CustomResult}; +use common_enums::enums; +use common_utils::{ + consts::{PROPHETPAY_REDIRECT_URL, PROPHETPAY_TOKEN}, + errors::CustomResult, + request::Method, +}; use error_stack::ResultExt; +use hyperswitch_domain_models::{ + payment_method_data::{CardRedirectData, PaymentMethodData}, + router_data::{ConnectorAuthType, ErrorResponse, RouterData}, + router_flow_types::refunds::Execute, + router_request_types::{ + CompleteAuthorizeData, CompleteAuthorizeRedirectResponse, PaymentsAuthorizeData, ResponseId, + }, + router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData}, + types, +}; +use hyperswitch_interfaces::{api, consts::NO_ERROR_CODE, errors}; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use url::Url; use crate::{ - connector::utils::{self, to_connector_meta}, - consts as const_val, - core::errors, - services, - types::{self, api, domain, storage::enums}, + types::{RefundsResponseRouterData, ResponseRouterData}, + utils::{self, to_connector_meta}, }; pub struct ProphetpayRouterData { @@ -38,11 +51,11 @@ pub struct ProphetpayAuthType { pub(super) profile_id: Secret, } -impl TryFrom<&types::ConnectorAuthType> for ProphetpayAuthType { +impl TryFrom<&ConnectorAuthType> for ProphetpayAuthType { type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + fn try_from(auth_type: &ConnectorAuthType) -> Result { match auth_type { - types::ConnectorAuthType::SignatureKey { + ConnectorAuthType::SignatureKey { api_key, key1, api_secret, @@ -124,9 +137,7 @@ impl TryFrom<&ProphetpayRouterData<&types::PaymentsAuthorizeRouterData>> ) -> Result { if item.router_data.request.currency == api_models::enums::Currency::USD { match item.router_data.request.payment_method_data.clone() { - domain::PaymentMethodData::CardRedirect( - domain::payments::CardRedirectData::CardRedirect {}, - ) => { + PaymentMethodData::CardRedirect(CardRedirectData::CardRedirect {}) => { let auth_data = ProphetpayAuthType::try_from(&item.router_data.connector_auth_type)?; Ok(Self { @@ -165,26 +176,21 @@ pub struct ProphetpayTokenResponse { impl TryFrom< - types::ResponseRouterData< - F, - ProphetpayTokenResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, - >, - > for types::RouterData + ResponseRouterData, + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, ProphetpayTokenResponse, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, + PaymentsAuthorizeData, + PaymentsResponseData, >, ) -> Result { let url_data = format!( "{}{}", - consts::PROPHETPAY_REDIRECT_URL, + PROPHETPAY_REDIRECT_URL, item.response.hosted_tokenize_id.expose() ); @@ -199,8 +205,8 @@ impl Ok(Self { status: enums::AttemptStatus::AuthenticationPending, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::NoResponseId, + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::NoResponseId, redirection_data: Box::new(redirection_data), mandate_reference: Box::new(None), connector_metadata: None, @@ -217,7 +223,7 @@ impl fn get_redirect_url_form( mut redirect_url: Url, complete_auth_url: Option, -) -> CustomResult { +) -> CustomResult { let mut form_fields = HashMap::::new(); form_fields.insert( @@ -230,9 +236,9 @@ fn get_redirect_url_form( // Do not include query params in the endpoint redirect_url.set_query(None); - Ok(services::RedirectForm::Form { + Ok(RedirectForm::Form { endpoint: redirect_url.to_string(), - method: services::Method::Get, + method: Method::Get, form_fields, }) } @@ -271,7 +277,7 @@ impl TryFrom<&ProphetpayRouterData<&types::PaymentsCompleteAuthorizeRouterData>> } fn get_card_token( - response: Option, + response: Option, ) -> CustomResult { let res = response.ok_or(errors::ConnectorError::MissingRequiredField { field_name: "redirect_response", @@ -298,7 +304,7 @@ fn get_card_token( .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; for (key, val) in queries_params { - if key.as_str() == consts::PROPHETPAY_TOKEN { + if key.as_str() == PROPHETPAY_TOKEN { return Ok(val); } } @@ -372,21 +378,21 @@ pub struct ProphetpayCardTokenData { impl TryFrom< - types::ResponseRouterData< + ResponseRouterData< F, ProphetpayCompleteAuthResponse, - types::CompleteAuthorizeData, - types::PaymentsResponseData, + CompleteAuthorizeData, + PaymentsResponseData, >, - > for types::RouterData + > for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< + item: ResponseRouterData< F, ProphetpayCompleteAuthResponse, - types::CompleteAuthorizeData, - types::PaymentsResponseData, + CompleteAuthorizeData, + PaymentsResponseData, >, ) -> Result { if item.response.success { @@ -397,10 +403,8 @@ impl let connector_metadata = serde_json::to_value(card_token_data).ok(); Ok(Self { status: enums::AttemptStatus::Charged, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( - item.response.transaction_id, - ), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(item.response.transaction_id), redirection_data: Box::new(None), mandate_reference: Box::new(None), connector_metadata, @@ -414,7 +418,7 @@ impl } else { Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(types::ErrorResponse { + response: Err(ErrorResponse { code: item.response.response_code, message: item.response.response_text.clone(), reason: Some(item.response.response_text), @@ -437,21 +441,18 @@ pub struct ProphetpaySyncResponse { pub transaction_id: String, } -impl - TryFrom> - for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData, + item: ResponseRouterData, ) -> Result { if item.response.success { Ok(Self { status: enums::AttemptStatus::Charged, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( - item.response.transaction_id, - ), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(item.response.transaction_id), redirection_data: Box::new(None), mandate_reference: Box::new(None), connector_metadata: None, @@ -465,8 +466,8 @@ impl } else { Ok(Self { status: enums::AttemptStatus::Failure, - response: Err(types::ErrorResponse { - code: const_val::NO_ERROR_CODE.to_string(), + response: Err(ErrorResponse { + code: NO_ERROR_CODE.to_string(), message: item.response.response_text.clone(), reason: Some(item.response.response_text), status_code: item.http_code, @@ -488,21 +489,18 @@ pub struct ProphetpayVoidResponse { pub transaction_id: String, } -impl - TryFrom> - for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData, + item: ResponseRouterData, ) -> Result { if item.response.success { Ok(Self { status: enums::AttemptStatus::Voided, - response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( - item.response.transaction_id, - ), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(item.response.transaction_id), redirection_data: Box::new(None), mandate_reference: Box::new(None), connector_metadata: None, @@ -516,8 +514,8 @@ impl } else { Ok(Self { status: enums::AttemptStatus::VoidFailed, - response: Err(types::ErrorResponse { - code: const_val::NO_ERROR_CODE.to_string(), + response: Err(ErrorResponse { + code: NO_ERROR_CODE.to_string(), message: item.response.response_text.clone(), reason: Some(item.response.response_text), status_code: item.http_code, @@ -601,16 +599,16 @@ pub struct ProphetpayRefundResponse { pub tran_seq_number: Option, } -impl TryFrom> - for types::RefundsRouterData +impl TryFrom> + for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { if item.response.success { Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { // no refund id is generated, tranSeqNumber is kept for future usage connector_refund_id: item.response.tran_seq_number.ok_or( errors::ConnectorError::MissingRequiredField { @@ -624,8 +622,8 @@ impl TryFrom TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { if item.response.success { Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { // no refund id is generated, rather transaction id is used for referring to status in refund also connector_refund_id: item.data.request.connector_transaction_id.clone(), refund_status: enums::RefundStatus::Success, @@ -664,8 +662,8 @@ impl TryFrom(&self, connectors: &'a settings::Connectors) -> &'a str { + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { connectors.rapyd.base_url.as_ref() } fn get_auth_header( &self, - _auth_type: &types::ConnectorAuthType, - ) -> CustomResult)>, errors::ConnectorError> { + _auth_type: &ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![]) } fn build_error_response( &self, - res: types::Response, + res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { let response: Result< @@ -139,7 +155,7 @@ impl ConnectorValidation for Rapyd { match capture_method { enums::CaptureMethod::Automatic | enums::CaptureMethod::Manual => Ok(()), enums::CaptureMethod::ManualMultiple | enums::CaptureMethod::Scheduled => Err( - connector_utils::construct_not_supported_error_report(capture_method, self.id()), + construct_not_supported_error_report(capture_method, self.id()), ), } } @@ -149,39 +165,22 @@ impl api::ConnectorAccessToken for Rapyd {} impl api::PaymentToken for Rapyd {} -impl - services::ConnectorIntegration< - api::PaymentMethodToken, - types::PaymentMethodTokenizationData, - types::PaymentsResponseData, - > for Rapyd +impl ConnectorIntegration + for Rapyd { // Not Implemented (R) } -impl - services::ConnectorIntegration< - api::AccessTokenAuth, - types::AccessTokenRequestData, - types::AccessToken, - > for Rapyd -{ -} +impl ConnectorIntegration for Rapyd {} impl api::PaymentAuthorize for Rapyd {} -impl - services::ConnectorIntegration< - api::Authorize, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, - > for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn get_headers( &self, - _req: &types::PaymentsAuthorizeRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![( headers::CONTENT_TYPE.to_string(), types::PaymentsAuthorizeType::get_content_type(self) @@ -196,16 +195,16 @@ impl fn get_url( &self, - _req: &types::PaymentsAuthorizeRouterData, - connectors: &settings::Connectors, + _req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/v1/payments", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::PaymentsAuthorizeRouterData, - _connectors: &settings::Connectors, + req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, ) -> CustomResult { let amount = convert_amount( self.amount_converter, @@ -219,13 +218,9 @@ impl fn build_request( &self, - req: &types::RouterData< - api::Authorize, - types::PaymentsAuthorizeData, - types::PaymentsResponseData, - >, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &RouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { let timestamp = date_time::now_unix_timestamp(); let salt = Alphanumeric.sample_string(&mut rand::thread_rng(), 12); @@ -240,8 +235,8 @@ impl ("timestamp".to_string(), timestamp.to_string().into()), ("signature".to_string(), signature.into_masked()), ]; - let request = services::RequestBuilder::new() - .method(services::Method::Post) + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsAuthorizeType::get_url( self, req, connectors, )?) @@ -259,17 +254,17 @@ impl fn handle_response( &self, - data: &types::PaymentsAuthorizeRouterData, + data: &PaymentsAuthorizeRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult { + res: Response, + ) -> CustomResult { let response: rapyd::RapydPaymentsResponse = res .response .parse_struct("Rapyd PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -279,7 +274,7 @@ impl fn get_error_response( &self, - res: types::Response, + res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { self.build_error_response(res, event_builder) @@ -289,22 +284,12 @@ impl impl api::Payment for Rapyd {} impl api::MandateSetup for Rapyd {} -impl - services::ConnectorIntegration< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - > for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn build_request( &self, - _req: &types::RouterData< - api::SetupMandate, - types::SetupMandateRequestData, - types::PaymentsResponseData, - >, - _connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + _req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { Err( errors::ConnectorError::NotImplemented("Setup Mandate flow for Rapyd".to_string()) .into(), @@ -314,18 +299,12 @@ impl impl api::PaymentVoid for Rapyd {} -impl - services::ConnectorIntegration< - api::Void, - types::PaymentsCancelData, - types::PaymentsResponseData, - > for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn get_headers( &self, - _req: &types::PaymentsCancelRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &PaymentsCancelRouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![( headers::CONTENT_TYPE.to_string(), types::PaymentsVoidType::get_content_type(self) @@ -340,8 +319,8 @@ impl fn get_url( &self, - req: &types::PaymentsCancelRouterData, - connectors: &settings::Connectors, + req: &PaymentsCancelRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!( "{}/v1/payments/{}", @@ -352,9 +331,9 @@ impl fn build_request( &self, - req: &types::PaymentsCancelRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &PaymentsCancelRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { let timestamp = date_time::now_unix_timestamp(); let salt = Alphanumeric.sample_string(&mut rand::thread_rng(), 12); @@ -369,8 +348,8 @@ impl ("timestamp".to_string(), timestamp.to_string().into()), ("signature".to_string(), signature.into_masked()), ]; - let request = services::RequestBuilder::new() - .method(services::Method::Delete) + let request = RequestBuilder::new() + .method(Method::Delete) .url(&types::PaymentsVoidType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?) @@ -381,17 +360,17 @@ impl fn handle_response( &self, - data: &types::PaymentsCancelRouterData, + data: &PaymentsCancelRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult { + res: Response, + ) -> CustomResult { let response: rapyd::RapydPaymentsResponse = res .response .parse_struct("Rapyd PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -401,7 +380,7 @@ impl fn get_error_response( &self, - res: types::Response, + res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { self.build_error_response(res, event_builder) @@ -409,15 +388,12 @@ impl } impl api::PaymentSync for Rapyd {} -impl - services::ConnectorIntegration - for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn get_headers( &self, - _req: &types::PaymentsSyncRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &PaymentsSyncRouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![( headers::CONTENT_TYPE.to_string(), types::PaymentsSyncType::get_content_type(self) @@ -432,8 +408,8 @@ impl fn get_url( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, + req: &PaymentsSyncRouterData, + connectors: &Connectors, ) -> CustomResult { let id = req.request.connector_transaction_id.clone(); Ok(format!( @@ -446,9 +422,9 @@ impl fn build_request( &self, - req: &types::PaymentsSyncRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { let timestamp = date_time::now_unix_timestamp(); let salt = Alphanumeric.sample_string(&mut rand::thread_rng(), 12); @@ -468,8 +444,8 @@ impl ("timestamp".to_string(), timestamp.to_string().into()), ("signature".to_string(), signature.into_masked()), ]; - let request = services::RequestBuilder::new() - .method(services::Method::Get) + let request = RequestBuilder::new() + .method(Method::Get) .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) @@ -480,7 +456,7 @@ impl fn get_error_response( &self, - res: types::Response, + res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { self.build_error_response(res, event_builder) @@ -488,17 +464,17 @@ impl fn handle_response( &self, - data: &types::PaymentsSyncRouterData, + data: &PaymentsSyncRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult { + res: Response, + ) -> CustomResult { let response: rapyd::RapydPaymentsResponse = res .response .parse_struct("Rapyd PaymentResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -508,18 +484,12 @@ impl } impl api::PaymentCapture for Rapyd {} -impl - services::ConnectorIntegration< - api::Capture, - types::PaymentsCaptureData, - types::PaymentsResponseData, - > for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn get_headers( &self, - _req: &types::PaymentsCaptureRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &PaymentsCaptureRouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![( headers::CONTENT_TYPE.to_string(), types::PaymentsCaptureType::get_content_type(self) @@ -534,8 +504,8 @@ impl fn get_request_body( &self, - req: &types::PaymentsCaptureRouterData, - _connectors: &settings::Connectors, + req: &PaymentsCaptureRouterData, + _connectors: &Connectors, ) -> CustomResult { let amount = convert_amount( self.amount_converter, @@ -549,9 +519,9 @@ impl fn build_request( &self, - req: &types::PaymentsCaptureRouterData, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { let timestamp = date_time::now_unix_timestamp(); let salt = Alphanumeric.sample_string(&mut rand::thread_rng(), 12); @@ -570,8 +540,8 @@ impl ("timestamp".to_string(), timestamp.to_string().into()), ("signature".to_string(), signature.into_masked()), ]; - let request = services::RequestBuilder::new() - .method(services::Method::Post) + let request = RequestBuilder::new() + .method(Method::Post) .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsCaptureType::get_headers( @@ -587,10 +557,10 @@ impl fn handle_response( &self, - data: &types::PaymentsCaptureRouterData, + data: &PaymentsCaptureRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult { + res: Response, + ) -> CustomResult { let response: rapyd::RapydPaymentsResponse = res .response .parse_struct("RapydPaymentResponse") @@ -599,7 +569,7 @@ impl event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -609,8 +579,8 @@ impl fn get_url( &self, - req: &types::PaymentsCaptureRouterData, - connectors: &settings::Connectors, + req: &PaymentsCaptureRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!( "{}/v1/payments/{}/capture", @@ -621,7 +591,7 @@ impl fn get_error_response( &self, - res: types::Response, + res: Response, event_builder: Option<&mut ConnectorEvent>, ) -> CustomResult { self.build_error_response(res, event_builder) @@ -630,13 +600,7 @@ impl impl api::PaymentSession for Rapyd {} -impl - services::ConnectorIntegration< - api::Session, - types::PaymentsSessionData, - types::PaymentsResponseData, - > for Rapyd -{ +impl ConnectorIntegration for Rapyd { //TODO: implement sessions flow } @@ -644,14 +608,12 @@ impl api::Refund for Rapyd {} impl api::RefundExecute for Rapyd {} impl api::RefundSync for Rapyd {} -impl services::ConnectorIntegration - for Rapyd -{ +impl ConnectorIntegration for Rapyd { fn get_headers( &self, - _req: &types::RefundsRouterData, - _connectors: &settings::Connectors, - ) -> CustomResult)>, errors::ConnectorError> { + _req: &RefundsRouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { Ok(vec![( headers::CONTENT_TYPE.to_string(), types::RefundExecuteType::get_content_type(self) @@ -666,16 +628,16 @@ impl services::ConnectorIntegration, - connectors: &settings::Connectors, + _req: &RefundsRouterData, + connectors: &Connectors, ) -> CustomResult { Ok(format!("{}/v1/refunds", self.base_url(connectors))) } fn get_request_body( &self, - req: &types::RefundsRouterData, - _connectors: &settings::Connectors, + req: &RefundsRouterData, + _connectors: &Connectors, ) -> CustomResult { let amount = convert_amount( self.amount_converter, @@ -690,9 +652,9 @@ impl services::ConnectorIntegration, - connectors: &settings::Connectors, - ) -> CustomResult, errors::ConnectorError> { + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { let timestamp = date_time::now_unix_timestamp(); let salt = Alphanumeric.sample_string(&mut rand::thread_rng(), 12); @@ -707,8 +669,8 @@ impl services::ConnectorIntegration, + data: &RefundsRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult, errors::ConnectorError> { + res: Response, + ) -> CustomResult, errors::ConnectorError> { let response: rapyd::RefundResponse = res .response .parse_struct("rapyd RefundResponse") .change_context(errors::ConnectorError::RequestEncodingFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -741,30 +703,28 @@ impl services::ConnectorIntegration, ) -> CustomResult { self.build_error_response(res, event_builder) } } -impl services::ConnectorIntegration - for Rapyd -{ +impl ConnectorIntegration for Rapyd { // default implementation of build_request method will be executed fn handle_response( &self, - data: &types::RefundSyncRouterData, + data: &RefundSyncRouterData, event_builder: Option<&mut ConnectorEvent>, - res: types::Response, - ) -> CustomResult { + res: Response, + ) -> CustomResult { let response: rapyd::RefundResponse = res .response .parse_struct("rapyd RefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; event_builder.map(|i| i.set_response_body(&response)); router_env::logger::info!(connector_response=?response); - types::RouterData::try_from(types::ResponseRouterData { + RouterData::try_from(ResponseRouterData { response, data: data.clone(), http_code: res.status_code, @@ -774,21 +734,21 @@ impl services::ConnectorIntegration, + _request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { Ok(Box::new(crypto::HmacSha256)) } fn get_webhook_source_verification_signature( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { - let base64_signature = connector_utils::get_header_key_value("signature", request.headers)?; - let signature = consts::BASE64_ENGINE_URL_SAFE + let base64_signature = get_header_key_value("signature", request.headers)?; + let signature = BASE64_ENGINE_URL_SAFE .decode(base64_signature.as_bytes()) .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?; Ok(signature) @@ -796,18 +756,18 @@ impl api::IncomingWebhook for Rapyd { fn get_webhook_source_verification_message( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, merchant_id: &common_utils::id_type::MerchantId, connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets, ) -> CustomResult, errors::ConnectorError> { - let host = connector_utils::get_header_key_value("host", request.headers)?; + let host = get_header_key_value("host", request.headers)?; let connector = self.id(); let url_path = format!( "https://{host}/webhooks/{}/{connector}", merchant_id.get_string_repr() ); - let salt = connector_utils::get_header_key_value("salt", request.headers)?; - let timestamp = connector_utils::get_header_key_value("timestamp", request.headers)?; + let salt = get_header_key_value("salt", request.headers)?; + let timestamp = get_header_key_value("timestamp", request.headers)?; let stringify_auth = String::from_utf8(connector_webhook_secrets.secret.to_vec()) .change_context(errors::ConnectorError::WebhookSourceVerificationFailed) .attach_printable("Could not convert secret to UTF-8")?; @@ -830,7 +790,7 @@ impl api::IncomingWebhook for Rapyd { async fn verify_webhook_source( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, merchant_id: &common_utils::id_type::MerchantId, connector_webhook_details: Option, _connector_account_details: crypto::Encryptable>, @@ -870,7 +830,7 @@ impl api::IncomingWebhook for Rapyd { fn get_webhook_object_reference_id( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult { let webhook: transformers::RapydIncomingWebhook = request .body @@ -900,8 +860,8 @@ impl api::IncomingWebhook for Rapyd { fn get_webhook_event_type( &self, - request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { let webhook: transformers::RapydIncomingWebhook = request .body .parse_struct("RapydIncomingWebhook") @@ -909,34 +869,32 @@ impl api::IncomingWebhook for Rapyd { Ok(match webhook.webhook_type { rapyd::RapydWebhookObjectEventType::PaymentCompleted | rapyd::RapydWebhookObjectEventType::PaymentCaptured => { - api::IncomingWebhookEvent::PaymentIntentSuccess + IncomingWebhookEvent::PaymentIntentSuccess } rapyd::RapydWebhookObjectEventType::PaymentFailed => { - api::IncomingWebhookEvent::PaymentIntentFailure + IncomingWebhookEvent::PaymentIntentFailure } rapyd::RapydWebhookObjectEventType::PaymentRefundFailed | rapyd::RapydWebhookObjectEventType::PaymentRefundRejected => { - api::IncomingWebhookEvent::RefundFailure + IncomingWebhookEvent::RefundFailure } rapyd::RapydWebhookObjectEventType::RefundCompleted => { - api::IncomingWebhookEvent::RefundSuccess + IncomingWebhookEvent::RefundSuccess } rapyd::RapydWebhookObjectEventType::PaymentDisputeCreated => { - api::IncomingWebhookEvent::DisputeOpened - } - rapyd::RapydWebhookObjectEventType::Unknown => { - api::IncomingWebhookEvent::EventNotSupported + IncomingWebhookEvent::DisputeOpened } + rapyd::RapydWebhookObjectEventType::Unknown => IncomingWebhookEvent::EventNotSupported, rapyd::RapydWebhookObjectEventType::PaymentDisputeUpdated => match webhook.data { - rapyd::WebhookData::Dispute(data) => api::IncomingWebhookEvent::from(data.status), - _ => api::IncomingWebhookEvent::EventNotSupported, + rapyd::WebhookData::Dispute(data) => IncomingWebhookEvent::from(data.status), + _ => IncomingWebhookEvent::EventNotSupported, }, }) } fn get_webhook_resource_object( &self, - request: &api::IncomingWebhookRequestDetails<'_>, + request: &IncomingWebhookRequestDetails<'_>, ) -> CustomResult, errors::ConnectorError> { let webhook: transformers::RapydIncomingWebhook = request .body @@ -962,8 +920,8 @@ impl api::IncomingWebhook for Rapyd { fn get_dispute_details( &self, - request: &api::IncomingWebhookRequestDetails<'_>, - ) -> CustomResult { + request: &IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { let webhook: transformers::RapydIncomingWebhook = request .body .parse_struct("RapydIncomingWebhook") @@ -972,7 +930,7 @@ impl api::IncomingWebhook for Rapyd { transformers::WebhookData::Dispute(dispute_data) => Ok(dispute_data), _ => Err(errors::ConnectorError::WebhookBodyDecodingFailed), }?; - Ok(api::disputes::DisputePayload { + Ok(DisputePayload { amount: webhook_dispute_data.amount.to_string(), currency: webhook_dispute_data.currency, dispute_stage: api_models::enums::DisputeStage::Dispute, diff --git a/crates/router/src/connector/rapyd/transformers.rs b/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs similarity index 82% rename from crates/router/src/connector/rapyd/transformers.rs rename to crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs index b83ffcec4124..4f9f276c1913 100644 --- a/crates/router/src/connector/rapyd/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/rapyd/transformers.rs @@ -1,17 +1,23 @@ -use common_utils::types::MinorUnit; +use common_enums::enums; +use common_utils::{ext_traits::OptionExt, request::Method, types::MinorUnit}; use error_stack::ResultExt; +use hyperswitch_domain_models::{ + payment_method_data::{PaymentMethodData, WalletData}, + router_data::{ConnectorAuthType, ErrorResponse, RouterData}, + router_flow_types::refunds::{Execute, RSync}, + router_request_types::ResponseId, + router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData}, + types, +}; +use hyperswitch_interfaces::{consts::NO_ERROR_CODE, errors}; +use masking::Secret; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; use url::Url; use crate::{ - connector::utils::{PaymentsAuthorizeRequestData, RouterData}, - consts, - core::errors, - pii::Secret, - services, - types::{self, api, domain, storage::enums, transformers::ForeignFrom}, - utils::OptionExt, + types::{RefundsResponseRouterData, ResponseRouterData}, + utils::{PaymentsAuthorizeRequestData, RouterData as _}, }; #[derive(Debug, Serialize)] @@ -92,7 +98,7 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay item: &RapydRouterData<&types::PaymentsAuthorizeRouterData>, ) -> Result { let (capture, payment_method_options) = match item.router_data.payment_method { - diesel_models::enums::PaymentMethod::Card => { + enums::PaymentMethod::Card => { let three_ds_enabled = matches!( item.router_data.auth_type, enums::AuthenticationType::ThreeDs @@ -111,7 +117,7 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay _ => (None, None), }; let payment_method = match item.router_data.request.payment_method_data { - domain::PaymentMethodData::Card(ref ccard) => { + PaymentMethodData::Card(ref ccard) => { Some(PaymentMethod { pm_type: "in_amex_card".to_owned(), //[#369] Map payment method type based on country fields: Some(PaymentFields { @@ -129,13 +135,13 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay digital_wallet: None, }) } - domain::PaymentMethodData::Wallet(ref wallet_data) => { + PaymentMethodData::Wallet(ref wallet_data) => { let digital_wallet = match wallet_data { - domain::WalletData::GooglePay(data) => Some(RapydWallet { + WalletData::GooglePay(data) => Some(RapydWallet { payment_type: "google_pay".to_string(), token: Some(Secret::new(data.tokenization_data.token.to_owned())), }), - domain::WalletData::ApplePay(data) => Some(RapydWallet { + WalletData::ApplePay(data) => Some(RapydWallet { payment_type: "apple_pay".to_string(), token: Some(Secret::new(data.payment_data.to_string())), }), @@ -175,10 +181,10 @@ pub struct RapydAuthType { pub secret_key: Secret, } -impl TryFrom<&types::ConnectorAuthType> for RapydAuthType { +impl TryFrom<&ConnectorAuthType> for RapydAuthType { type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { - if let types::ConnectorAuthType::BodyKey { api_key, key1 } = auth_type { + fn try_from(auth_type: &ConnectorAuthType) -> Result { + if let ConnectorAuthType::BodyKey { api_key, key1 } = auth_type { Ok(Self { access_key: api_key.to_owned(), secret_key: key1.to_owned(), @@ -209,28 +215,24 @@ pub enum RapydPaymentStatus { New, } -impl ForeignFrom<(RapydPaymentStatus, NextAction)> for enums::AttemptStatus { - fn foreign_from(item: (RapydPaymentStatus, NextAction)) -> Self { - let (status, next_action) = item; - match (status, next_action) { - (RapydPaymentStatus::Closed, _) => Self::Charged, - ( - RapydPaymentStatus::Active, - NextAction::ThreedsVerification | NextAction::PendingConfirmation, - ) => Self::AuthenticationPending, - ( - RapydPaymentStatus::Active, - NextAction::PendingCapture | NextAction::NotApplicable, - ) => Self::Authorized, - ( - RapydPaymentStatus::CanceledByClientOrBank - | RapydPaymentStatus::Expired - | RapydPaymentStatus::ReversedByRapyd, - _, - ) => Self::Voided, - (RapydPaymentStatus::Error, _) => Self::Failure, - (RapydPaymentStatus::New, _) => Self::Authorizing, +fn get_status(status: RapydPaymentStatus, next_action: NextAction) -> enums::AttemptStatus { + match (status, next_action) { + (RapydPaymentStatus::Closed, _) => enums::AttemptStatus::Charged, + ( + RapydPaymentStatus::Active, + NextAction::ThreedsVerification | NextAction::PendingConfirmation, + ) => enums::AttemptStatus::AuthenticationPending, + (RapydPaymentStatus::Active, NextAction::PendingCapture | NextAction::NotApplicable) => { + enums::AttemptStatus::Authorized } + ( + RapydPaymentStatus::CanceledByClientOrBank + | RapydPaymentStatus::Expired + | RapydPaymentStatus::ReversedByRapyd, + _, + ) => enums::AttemptStatus::Voided, + (RapydPaymentStatus::Error, _) => enums::AttemptStatus::Failure, + (RapydPaymentStatus::New, _) => enums::AttemptStatus::Authorizing, } } @@ -357,12 +359,12 @@ pub struct RefundResponseData { pub failure_reason: Option, } -impl TryFrom> - for types::RefundsRouterData +impl TryFrom> + for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { let (connector_refund_id, refund_status) = match item.response.data { Some(data) => (data.id, enums::RefundStatus::from(data.status)), @@ -372,7 +374,7 @@ impl TryFrom> ), }; Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id, refund_status, }), @@ -381,12 +383,10 @@ impl TryFrom> } } -impl TryFrom> - for types::RefundsRouterData -{ +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: RefundsResponseRouterData, ) -> Result { let (connector_refund_id, refund_status) = match item.response.data { Some(data) => (data.id, enums::RefundStatus::from(data.status)), @@ -396,7 +396,7 @@ impl TryFrom> ), }; Ok(Self { - response: Ok(types::RefundsResponseData { + response: Ok(RefundsResponseData { connector_refund_id, refund_status, }), @@ -425,24 +425,21 @@ impl TryFrom<&RapydRouterData<&types::PaymentsCaptureRouterData>> for CaptureReq } } -impl - TryFrom> - for types::RouterData +impl TryFrom> + for RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData, + item: ResponseRouterData, ) -> Result { let (status, response) = match &item.response.data { Some(data) => { - let attempt_status = enums::AttemptStatus::foreign_from(( - data.status.to_owned(), - data.next_action.to_owned(), - )); + let attempt_status = + get_status(data.status.to_owned(), data.next_action.to_owned()); match attempt_status { - diesel_models::enums::AttemptStatus::Failure => ( + enums::AttemptStatus::Failure => ( enums::AttemptStatus::Failure, - Err(types::ErrorResponse { + Err(ErrorResponse { code: data .failure_code .to_owned() @@ -466,15 +463,13 @@ impl }) .transpose()?; - let redirection_data = redirection_url - .map(|url| services::RedirectForm::from((url, services::Method::Get))); + let redirection_data = + redirection_url.map(|url| RedirectForm::from((url, Method::Get))); ( attempt_status, - Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId( - data.id.to_owned(), - ), //transaction_id is also the field but this id is used to initiate a refund + Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(data.id.to_owned()), //transaction_id is also the field but this id is used to initiate a refund redirection_data: Box::new(redirection_data), mandate_reference: Box::new(None), connector_metadata: None, @@ -491,7 +486,7 @@ impl } None => ( enums::AttemptStatus::Failure, - Err(types::ErrorResponse { + Err(ErrorResponse { code: item.response.status.error_code, status_code: item.http_code, message: item.response.status.status.unwrap_or_default(), @@ -574,7 +569,7 @@ impl From for RapydPaymentsResponse { fn from(value: ResponseData) -> Self { Self { status: Status { - error_code: consts::NO_ERROR_CODE.to_owned(), + error_code: NO_ERROR_CODE.to_owned(), status: None, message: None, response_code: None, @@ -589,7 +584,7 @@ impl From for RefundResponse { fn from(value: RefundResponseData) -> Self { Self { status: Status { - error_code: consts::NO_ERROR_CODE.to_owned(), + error_code: NO_ERROR_CODE.to_owned(), status: None, message: None, response_code: None, diff --git a/crates/hyperswitch_connectors/src/connectors/razorpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/razorpay/transformers.rs index 3b2164dfc978..c799cf2594ee 100644 --- a/crates/hyperswitch_connectors/src/connectors/razorpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/razorpay/transformers.rs @@ -58,7 +58,6 @@ pub struct RazorpayPaymentsRequest { #[derive(Default, Debug, Serialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] - pub struct SecondFactor { txn_id: String, id: String, @@ -981,7 +980,6 @@ pub struct RazorpaySyncResponse { #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] - pub enum PsyncStatus { Charged, Pending, @@ -1054,7 +1052,6 @@ pub struct Refund { #[derive(Default, Debug, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] - pub enum RefundStatus { Success, Failure, @@ -1221,7 +1218,6 @@ impl From for enums::RefundStatus { #[derive(Default, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] - pub struct RefundResponse { txn_id: Option, refund: RefundRes, diff --git a/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs b/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs index 540bcaebaaeb..1973e622be1b 100644 --- a/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs @@ -1,4 +1,4 @@ -use api_models::{payments::AddressDetails, webhooks::IncomingWebhookEvent}; +use api_models::webhooks::IncomingWebhookEvent; use cards::CardNumber; use common_enums::enums; use common_utils::{ @@ -555,7 +555,9 @@ where } } -fn get_address_details(address_details: Option<&AddressDetails>) -> Option
{ +fn get_address_details( + address_details: Option<&hyperswitch_domain_models::address::AddressDetails>, +) -> Option
{ address_details.map(|address| Address { line1: address.line1.clone(), line2: address.line1.clone(), diff --git a/crates/hyperswitch_connectors/src/connectors/tsys/transformers.rs b/crates/hyperswitch_connectors/src/connectors/tsys/transformers.rs index cd9fe63e4a79..27b9daaa5798 100644 --- a/crates/hyperswitch_connectors/src/connectors/tsys/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/tsys/transformers.rs @@ -457,7 +457,6 @@ pub struct TsysCaptureRequest { #[derive(Debug, Serialize)] #[serde(rename_all = "PascalCase")] - pub struct TsysPaymentsCaptureRequest { capture: TsysCaptureRequest, } diff --git a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs index 89ee8d1b29b6..e3ebcf490de1 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs @@ -1,4 +1,3 @@ -use api_models::payments; use common_enums::enums::{AttemptStatus, BankNames, CaptureMethod, CountryAlpha2, Currency}; use common_utils::{pii::Email, request::Method}; use hyperswitch_domain_models::{ @@ -418,15 +417,18 @@ fn make_bank_redirect_request( } fn get_address( - billing: &payments::Address, -) -> Option<(&payments::Address, &payments::AddressDetails)> { + billing: &hyperswitch_domain_models::address::Address, +) -> Option<( + &hyperswitch_domain_models::address::Address, + &hyperswitch_domain_models::address::AddressDetails, +)> { let address = billing.address.as_ref()?; address.country.as_ref()?; Some((billing, address)) } fn build_customer_info( - billing_address: &payments::Address, + billing_address: &hyperswitch_domain_models::address::Address, email: &Option, ) -> Result> { let (billing, address) = @@ -454,8 +456,8 @@ fn build_customer_info( }) } -impl From for BillingAddress { - fn from(value: payments::AddressDetails) -> Self { +impl From for BillingAddress { + fn from(value: hyperswitch_domain_models::address::AddressDetails) -> Self { Self { city: value.city, country_code: value.country, @@ -466,8 +468,8 @@ impl From for BillingAddress { } } -impl From for Shipping { - fn from(value: payments::AddressDetails) -> Self { +impl From for Shipping { + fn from(value: hyperswitch_domain_models::address::AddressDetails) -> Self { Self { city: value.city, country_code: value.country, diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs index be8f9bca3527..266fcc7d659b 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay.rs @@ -54,8 +54,8 @@ use response::{ WP_CORRELATION_ID, }; use ring::hmac; -use transformers::{self as worldpay}; +use self::transformers as worldpay; use crate::{ constants::headers, types::ResponseRouterData, diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index 8ecc3ad792ce..781d364a5977 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use api_models::payments::{Address, MandateIds, MandateReferenceId}; +use api_models::payments::{MandateIds, MandateReferenceId}; use base64::Engine; use common_enums::enums; use common_utils::{ @@ -8,6 +8,7 @@ use common_utils::{ }; use error_stack::ResultExt; use hyperswitch_domain_models::{ + address, payment_method_data::{PaymentMethodData, WalletData}, router_data::{ConnectorAuthType, ErrorResponse, RouterData}, router_flow_types::{Authorize, SetupMandate}, @@ -70,7 +71,7 @@ impl TryFrom> for WorldpayConnectorMetadataObject fn fetch_payment_instrument( payment_method: PaymentMethodData, - billing_address: Option<&Address>, + billing_address: Option<&address::Address>, mandate_ids: Option, ) -> CustomResult { match payment_method { @@ -232,7 +233,7 @@ trait WorldpayPaymentsRequestData { fn get_off_session(&self) -> Option; fn get_mandate_id(&self) -> Option; fn get_currency(&self) -> enums::Currency; - fn get_optional_billing_address(&self) -> Option<&Address>; + fn get_optional_billing_address(&self) -> Option<&address::Address>; fn get_connector_meta_data(&self) -> Option<&pii::SecretSerdeValue>; fn get_payment_method(&self) -> enums::PaymentMethod; fn get_payment_method_type(&self) -> Option; @@ -278,7 +279,7 @@ impl WorldpayPaymentsRequestData self.request.currency } - fn get_optional_billing_address(&self) -> Option<&Address> { + fn get_optional_billing_address(&self) -> Option<&address::Address> { self.get_optional_billing() } @@ -338,7 +339,7 @@ impl WorldpayPaymentsRequestData self.request.currency } - fn get_optional_billing_address(&self) -> Option<&Address> { + fn get_optional_billing_address(&self) -> Option<&address::Address> { self.get_optional_billing() } diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs index 25306458e8f7..b39f50bfe18f 100644 --- a/crates/hyperswitch_connectors/src/default_implementations.rs +++ b/crates/hyperswitch_connectors/src/default_implementations.rs @@ -92,8 +92,10 @@ default_imp_for_authorize_session_token!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -106,6 +108,7 @@ default_imp_for_authorize_session_token!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -116,8 +119,10 @@ default_imp_for_authorize_session_token!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -151,8 +156,10 @@ default_imp_for_calculate_tax!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -165,6 +172,7 @@ default_imp_for_calculate_tax!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -177,6 +185,8 @@ default_imp_for_calculate_tax!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -210,8 +220,10 @@ default_imp_for_session_update!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -224,6 +236,7 @@ default_imp_for_session_update!( connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -240,12 +253,14 @@ default_imp_for_session_update!( connectors::Payu, connectors::Fiuu, connectors::Globepay, + connectors::Gocardless, connectors::Worldline, connectors::Worldpay, connectors::Xendit, connectors::Zen, connectors::Zsl, connectors::Powertranz, + connectors::Prophetpay, connectors::Thunes, connectors::Tsys, connectors::Deutschebank, @@ -270,7 +285,9 @@ default_imp_for_post_session_tokens!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Bitpay, + connectors::Boku, connectors::Billwerk, connectors::Cashtocode, connectors::Coinbase, @@ -285,6 +302,7 @@ default_imp_for_post_session_tokens!( connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -300,10 +318,12 @@ default_imp_for_post_session_tokens!( connectors::Payu, connectors::Fiuu, connectors::Globepay, + connectors::Gocardless, connectors::Worldline, connectors::Worldpay, connectors::Xendit, connectors::Powertranz, + connectors::Prophetpay, connectors::Thunes, connectors::Tsys, connectors::Deutschebank, @@ -330,8 +350,10 @@ macro_rules! default_imp_for_complete_authorize { default_imp_for_complete_authorize!( connectors::Amazonpay, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -342,6 +364,7 @@ default_imp_for_complete_authorize!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -351,6 +374,7 @@ default_imp_for_complete_authorize!( connectors::Nexinets, connectors::Payeezy, connectors::Payu, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Stax, @@ -384,8 +408,10 @@ default_imp_for_incremental_authorization!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -398,6 +424,7 @@ default_imp_for_incremental_authorization!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -408,8 +435,10 @@ default_imp_for_incremental_authorization!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -445,8 +474,10 @@ default_imp_for_create_customer!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -471,6 +502,8 @@ default_imp_for_create_customer!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -507,6 +540,8 @@ default_imp_for_connector_redirect_response!( connectors::Amazonpay, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, + connectors::Bamboraapac, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -518,6 +553,7 @@ default_imp_for_connector_redirect_response!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -528,6 +564,8 @@ default_imp_for_connector_redirect_response!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -560,8 +598,10 @@ macro_rules! default_imp_for_pre_processing_steps{ default_imp_for_pre_processing_steps!( connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -583,8 +623,10 @@ default_imp_for_pre_processing_steps!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Stax, @@ -619,8 +661,10 @@ default_imp_for_post_processing_steps!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -633,6 +677,7 @@ default_imp_for_post_processing_steps!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -643,8 +688,10 @@ default_imp_for_post_processing_steps!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -680,8 +727,10 @@ default_imp_for_approve!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -694,6 +743,7 @@ default_imp_for_approve!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -704,8 +754,10 @@ default_imp_for_approve!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -741,8 +793,10 @@ default_imp_for_reject!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -755,6 +809,7 @@ default_imp_for_reject!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -765,8 +820,10 @@ default_imp_for_reject!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -802,8 +859,10 @@ default_imp_for_webhook_source_verification!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -816,6 +875,7 @@ default_imp_for_webhook_source_verification!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -826,8 +886,10 @@ default_imp_for_webhook_source_verification!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -864,8 +926,10 @@ default_imp_for_accept_dispute!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -878,6 +942,7 @@ default_imp_for_accept_dispute!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -888,8 +953,10 @@ default_imp_for_accept_dispute!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -925,8 +992,10 @@ default_imp_for_submit_evidence!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -939,6 +1008,7 @@ default_imp_for_submit_evidence!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -949,8 +1019,10 @@ default_imp_for_submit_evidence!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -986,8 +1058,10 @@ default_imp_for_defend_dispute!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1000,6 +1074,7 @@ default_imp_for_defend_dispute!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Inespay, connectors::Jpmorgan, connectors::Helcim, @@ -1010,8 +1085,10 @@ default_imp_for_defend_dispute!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1056,8 +1133,10 @@ default_imp_for_file_upload!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1070,6 +1149,7 @@ default_imp_for_file_upload!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1080,8 +1160,10 @@ default_imp_for_file_upload!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1110,8 +1192,10 @@ default_imp_for_payouts!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Cryptopay, connectors::Coinbase, @@ -1124,6 +1208,7 @@ default_imp_for_payouts!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1136,6 +1221,8 @@ default_imp_for_payouts!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1172,8 +1259,10 @@ default_imp_for_payouts_create!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1186,6 +1275,7 @@ default_imp_for_payouts_create!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1196,8 +1286,10 @@ default_imp_for_payouts_create!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1235,8 +1327,10 @@ default_imp_for_payouts_retrieve!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1249,6 +1343,7 @@ default_imp_for_payouts_retrieve!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1259,8 +1354,10 @@ default_imp_for_payouts_retrieve!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1298,8 +1395,10 @@ default_imp_for_payouts_eligibility!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1312,6 +1411,7 @@ default_imp_for_payouts_eligibility!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1322,8 +1422,10 @@ default_imp_for_payouts_eligibility!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1361,8 +1463,10 @@ default_imp_for_payouts_fulfill!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1375,6 +1479,7 @@ default_imp_for_payouts_fulfill!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1385,8 +1490,10 @@ default_imp_for_payouts_fulfill!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1424,8 +1531,10 @@ default_imp_for_payouts_cancel!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1438,6 +1547,7 @@ default_imp_for_payouts_cancel!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1448,8 +1558,10 @@ default_imp_for_payouts_cancel!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1487,8 +1599,10 @@ default_imp_for_payouts_quote!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1501,6 +1615,7 @@ default_imp_for_payouts_quote!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1511,8 +1626,10 @@ default_imp_for_payouts_quote!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1550,8 +1667,10 @@ default_imp_for_payouts_recipient!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1564,6 +1683,7 @@ default_imp_for_payouts_recipient!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1574,8 +1694,10 @@ default_imp_for_payouts_recipient!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1613,8 +1735,10 @@ default_imp_for_payouts_recipient_account!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1627,6 +1751,7 @@ default_imp_for_payouts_recipient_account!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1637,8 +1762,10 @@ default_imp_for_payouts_recipient_account!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1676,8 +1803,10 @@ default_imp_for_frm_sale!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1690,6 +1819,7 @@ default_imp_for_frm_sale!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1700,8 +1830,10 @@ default_imp_for_frm_sale!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1739,8 +1871,10 @@ default_imp_for_frm_checkout!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1753,6 +1887,7 @@ default_imp_for_frm_checkout!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1763,8 +1898,10 @@ default_imp_for_frm_checkout!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1802,8 +1939,10 @@ default_imp_for_frm_transaction!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1816,6 +1955,7 @@ default_imp_for_frm_transaction!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1826,8 +1966,10 @@ default_imp_for_frm_transaction!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1865,8 +2007,10 @@ default_imp_for_frm_fulfillment!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1879,6 +2023,7 @@ default_imp_for_frm_fulfillment!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1889,8 +2034,10 @@ default_imp_for_frm_fulfillment!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1928,8 +2075,10 @@ default_imp_for_frm_record_return!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1942,6 +2091,7 @@ default_imp_for_frm_record_return!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1952,8 +2102,10 @@ default_imp_for_frm_record_return!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1988,8 +2140,10 @@ default_imp_for_revoking_mandates!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -2002,6 +2156,7 @@ default_imp_for_revoking_mandates!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -2012,8 +2167,10 @@ default_imp_for_revoking_mandates!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, diff --git a/crates/hyperswitch_connectors/src/default_implementations_v2.rs b/crates/hyperswitch_connectors/src/default_implementations_v2.rs index 6a30a180fe7b..60e14ca35957 100644 --- a/crates/hyperswitch_connectors/src/default_implementations_v2.rs +++ b/crates/hyperswitch_connectors/src/default_implementations_v2.rs @@ -208,8 +208,10 @@ default_imp_for_new_connector_integration_payment!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -222,6 +224,7 @@ default_imp_for_new_connector_integration_payment!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -232,8 +235,10 @@ default_imp_for_new_connector_integration_payment!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -270,8 +275,10 @@ default_imp_for_new_connector_integration_refund!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -284,6 +291,7 @@ default_imp_for_new_connector_integration_refund!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -294,8 +302,10 @@ default_imp_for_new_connector_integration_refund!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -327,8 +337,10 @@ default_imp_for_new_connector_integration_connector_access_token!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -341,6 +353,7 @@ default_imp_for_new_connector_integration_connector_access_token!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -351,8 +364,10 @@ default_imp_for_new_connector_integration_connector_access_token!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -390,8 +405,10 @@ default_imp_for_new_connector_integration_accept_dispute!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -404,6 +421,7 @@ default_imp_for_new_connector_integration_accept_dispute!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -414,8 +432,10 @@ default_imp_for_new_connector_integration_accept_dispute!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -452,8 +472,10 @@ default_imp_for_new_connector_integration_submit_evidence!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -466,6 +488,7 @@ default_imp_for_new_connector_integration_submit_evidence!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -476,8 +499,10 @@ default_imp_for_new_connector_integration_submit_evidence!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -514,8 +539,10 @@ default_imp_for_new_connector_integration_defend_dispute!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -528,6 +555,7 @@ default_imp_for_new_connector_integration_defend_dispute!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -538,8 +566,10 @@ default_imp_for_new_connector_integration_defend_dispute!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -586,8 +616,10 @@ default_imp_for_new_connector_integration_file_upload!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -600,6 +632,7 @@ default_imp_for_new_connector_integration_file_upload!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -610,8 +643,10 @@ default_imp_for_new_connector_integration_file_upload!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -650,8 +685,10 @@ default_imp_for_new_connector_integration_payouts_create!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -664,6 +701,7 @@ default_imp_for_new_connector_integration_payouts_create!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -674,8 +712,10 @@ default_imp_for_new_connector_integration_payouts_create!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -714,8 +754,10 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -728,6 +770,7 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -738,8 +781,10 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -778,8 +823,10 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -792,6 +839,7 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -802,8 +850,10 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -842,8 +892,10 @@ default_imp_for_new_connector_integration_payouts_cancel!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -856,6 +908,7 @@ default_imp_for_new_connector_integration_payouts_cancel!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -866,8 +919,10 @@ default_imp_for_new_connector_integration_payouts_cancel!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -906,8 +961,10 @@ default_imp_for_new_connector_integration_payouts_quote!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -920,6 +977,7 @@ default_imp_for_new_connector_integration_payouts_quote!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -930,8 +988,10 @@ default_imp_for_new_connector_integration_payouts_quote!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -970,8 +1030,10 @@ default_imp_for_new_connector_integration_payouts_recipient!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -984,6 +1046,7 @@ default_imp_for_new_connector_integration_payouts_recipient!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -994,8 +1057,10 @@ default_imp_for_new_connector_integration_payouts_recipient!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1034,8 +1099,10 @@ default_imp_for_new_connector_integration_payouts_sync!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1048,6 +1115,7 @@ default_imp_for_new_connector_integration_payouts_sync!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1058,8 +1126,10 @@ default_imp_for_new_connector_integration_payouts_sync!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1098,8 +1168,10 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1112,6 +1184,7 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1122,8 +1195,10 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1160,8 +1235,10 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1174,6 +1251,7 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1184,8 +1262,10 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1224,8 +1304,10 @@ default_imp_for_new_connector_integration_frm_sale!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1238,6 +1320,7 @@ default_imp_for_new_connector_integration_frm_sale!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1248,8 +1331,10 @@ default_imp_for_new_connector_integration_frm_sale!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1288,8 +1373,10 @@ default_imp_for_new_connector_integration_frm_checkout!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1302,6 +1389,7 @@ default_imp_for_new_connector_integration_frm_checkout!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1312,8 +1400,10 @@ default_imp_for_new_connector_integration_frm_checkout!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1352,8 +1442,10 @@ default_imp_for_new_connector_integration_frm_transaction!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1366,6 +1458,7 @@ default_imp_for_new_connector_integration_frm_transaction!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1376,8 +1469,10 @@ default_imp_for_new_connector_integration_frm_transaction!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1416,8 +1511,10 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1430,6 +1527,7 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1440,8 +1538,10 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1480,8 +1580,10 @@ default_imp_for_new_connector_integration_frm_record_return!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1494,6 +1596,7 @@ default_imp_for_new_connector_integration_frm_record_return!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1504,8 +1607,10 @@ default_imp_for_new_connector_integration_frm_record_return!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, @@ -1541,8 +1646,10 @@ default_imp_for_new_connector_integration_revoking_mandates!( connectors::Airwallex, connectors::Amazonpay, connectors::Bambora, + connectors::Bamboraapac, connectors::Billwerk, connectors::Bitpay, + connectors::Boku, connectors::Cashtocode, connectors::Coinbase, connectors::Cryptopay, @@ -1555,6 +1662,7 @@ default_imp_for_new_connector_integration_revoking_mandates!( connectors::Fiuu, connectors::Forte, connectors::Globepay, + connectors::Gocardless, connectors::Helcim, connectors::Inespay, connectors::Jpmorgan, @@ -1565,8 +1673,10 @@ default_imp_for_new_connector_integration_revoking_mandates!( connectors::Payeezy, connectors::Payu, connectors::Powertranz, + connectors::Prophetpay, connectors::Mollie, connectors::Multisafepay, + connectors::Rapyd, connectors::Razorpay, connectors::Redsys, connectors::Shift4, diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index a7fe1cc4cd95..c60f8e79a500 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -1,6 +1,6 @@ use std::collections::{HashMap, HashSet}; -use api_models::payments::{self, Address, AddressDetails, PhoneDetails}; +use api_models::payments; use base64::Engine; use common_enums::{ enums, @@ -16,12 +16,13 @@ use common_utils::{ }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ + address::{Address, AddressDetails, PhoneDetails}, payment_method_data::{Card, PaymentMethodData}, router_data::{ ApplePayPredecryptData, ErrorResponse, PaymentMethodToken, RecurringMandatePaymentData, }, router_request_types::{ - AuthenticationData, BrowserInformation, CompleteAuthorizeData, + AuthenticationData, BrowserInformation, CompleteAuthorizeData, ConnectorCustomerData, PaymentMethodTokenizationData, PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSyncData, RefundsData, ResponseId, SetupMandateRequestData, @@ -119,7 +120,7 @@ where pub(crate) fn missing_field_err( message: &'static str, -) -> Box error_stack::Report + '_> { +) -> Box error_stack::Report + 'static> { Box::new(move || { errors::ConnectorError::MissingRequiredField { field_name: message, @@ -299,6 +300,7 @@ pub trait RouterData { fn get_optional_shipping_state(&self) -> Option>; fn get_optional_shipping_first_name(&self) -> Option>; fn get_optional_shipping_last_name(&self) -> Option>; + fn get_optional_shipping_full_name(&self) -> Option>; fn get_optional_shipping_phone_number(&self) -> Option>; fn get_optional_shipping_email(&self) -> Option; @@ -368,6 +370,12 @@ impl RouterData }) } + fn get_optional_shipping_full_name(&self) -> Option> { + self.get_optional_shipping() + .and_then(|shipping_details| shipping_details.address.as_ref()) + .and_then(|shipping_address| shipping_address.get_optional_full_name()) + } + fn get_optional_shipping_line1(&self) -> Option> { self.address.get_shipping().and_then(|shipping_address| { shipping_address @@ -1138,6 +1146,15 @@ impl PhoneDetailsData for PhoneDetails { } } +pub trait CustomerData { + fn get_email(&self) -> Result; +} + +impl CustomerData for ConnectorCustomerData { + fn get_email(&self) -> Result { + self.email.clone().ok_or_else(missing_field_err("email")) + } +} pub trait PaymentsAuthorizeRequestData { fn get_optional_language_from_browser_info(&self) -> Option; fn is_auto_capture(&self) -> Result; @@ -1167,6 +1184,7 @@ pub trait PaymentsAuthorizeRequestData { fn get_card_holder_name_from_additional_payment_method_data( &self, ) -> Result, Error>; + fn get_connector_mandate_request_reference_id(&self) -> Result; } impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData { @@ -1345,6 +1363,20 @@ impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData { .into()), } } + /// Attempts to retrieve the connector mandate reference ID as a `Result`. + fn get_connector_mandate_request_reference_id(&self) -> Result { + self.mandate_id + .as_ref() + .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id { + Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => { + connector_mandate_ids.get_connector_mandate_request_reference_id() + } + Some(payments::MandateReferenceId::NetworkMandateId(_)) + | None + | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None, + }) + .ok_or_else(missing_field_err("connector_mandate_request_reference_id")) + } } pub trait PaymentsCaptureRequestData { @@ -1504,6 +1536,7 @@ pub trait PaymentsCompleteAuthorizeRequestData { fn get_redirect_response_payload(&self) -> Result; fn get_complete_authorize_url(&self) -> Result; fn is_mandate_payment(&self) -> bool; + fn get_connector_mandate_request_reference_id(&self) -> Result; } impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData { @@ -1544,6 +1577,20 @@ impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData { .and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref()) .is_some() } + /// Attempts to retrieve the connector mandate reference ID as a `Result`. + fn get_connector_mandate_request_reference_id(&self) -> Result { + self.mandate_id + .as_ref() + .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id { + Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => { + connector_mandate_ids.get_connector_mandate_request_reference_id() + } + Some(payments::MandateReferenceId::NetworkMandateId(_)) + | None + | Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None, + }) + .ok_or_else(missing_field_err("connector_mandate_request_reference_id")) + } } pub trait AddressData { fn get_optional_full_name(&self) -> Option>; diff --git a/crates/hyperswitch_constraint_graph/src/graph.rs b/crates/hyperswitch_constraint_graph/src/graph.rs index 7c435fee2909..8d56406d2a37 100644 --- a/crates/hyperswitch_constraint_graph/src/graph.rs +++ b/crates/hyperswitch_constraint_graph/src/graph.rs @@ -120,7 +120,7 @@ where already_memo .clone() .map_err(|err| GraphError::AnalysisError(Arc::downgrade(&err))) - } else if let Some((initial_strength, initial_relation)) = cycle_map.get(&node_id).cloned() + } else if let Some((initial_strength, initial_relation)) = cycle_map.get(&node_id).copied() { let strength_relation = Strength::get_resolved_strength(initial_strength, strength); let relation_resolve = @@ -197,7 +197,7 @@ where if !unsatisfied.is_empty() { let err = Arc::new(AnalysisTrace::AllAggregation { unsatisfied, - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), }); @@ -264,7 +264,7 @@ where } else { let err = Arc::new(AnalysisTrace::AnyAggregation { unsatisfied: unsatisfied.clone(), - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), }); @@ -305,7 +305,7 @@ where expected: expected.iter().cloned().collect(), found: None, relation: vald.relation, - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), }); @@ -324,7 +324,7 @@ where expected: expected.iter().cloned().collect(), found: Some(ctx_value.clone()), relation: vald.relation, - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), }); @@ -402,7 +402,7 @@ where let err = Arc::new(AnalysisTrace::Value { value: val.clone(), relation: vald.relation, - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), predecessors: Some(error::ValueTracePredecessor::Mandatory(Box::new( trace.get_analysis_trace()?, @@ -437,7 +437,7 @@ where let err = Arc::new(AnalysisTrace::Value { value: val.clone(), relation: vald.relation, - info: self.node_info.get(vald.node_id).cloned().flatten(), + info: self.node_info.get(vald.node_id).copied().flatten(), metadata: self.node_metadata.get(vald.node_id).cloned().flatten(), predecessors: Some(error::ValueTracePredecessor::OneOf(errors.clone())), }); @@ -469,7 +469,7 @@ where value: val.clone(), relation, predecessors: None, - info: self.node_info.get(node_id).cloned().flatten(), + info: self.node_info.get(node_id).copied().flatten(), metadata: self.node_metadata.get(node_id).cloned().flatten(), }); memo.insert((node_id, relation, strength), Err(Arc::clone(&err))); diff --git a/crates/hyperswitch_domain_models/src/address.rs b/crates/hyperswitch_domain_models/src/address.rs index 85595c1ad9e3..c9beb359c433 100644 --- a/crates/hyperswitch_domain_models/src/address.rs +++ b/crates/hyperswitch_domain_models/src/address.rs @@ -11,15 +11,22 @@ impl masking::SerializableSecret for Address {} impl Address { /// Unify the address, giving priority to `self` when details are present in both - pub fn unify_address(self, other: Option<&Self>) -> Self { + pub fn unify_address(&self, other: Option<&Self>) -> Self { let other_address_details = other.and_then(|address| address.address.as_ref()); Self { address: self .address + .as_ref() .map(|address| address.unify_address_details(other_address_details)) .or(other_address_details.cloned()), - email: self.email.or(other.and_then(|other| other.email.clone())), - phone: self.phone.or(other.and_then(|other| other.phone.clone())), + email: self + .email + .clone() + .or(other.and_then(|other| other.email.clone())), + phone: self + .phone + .clone() + .or(other.and_then(|other| other.phone.clone())), } } } @@ -51,14 +58,14 @@ impl AddressDetails { } /// Unify the address details, giving priority to `self` when details are present in both - pub fn unify_address_details(self, other: Option<&Self>) -> Self { + pub fn unify_address_details(&self, other: Option<&Self>) -> Self { if let Some(other) = other { let (first_name, last_name) = if self .first_name .as_ref() .is_some_and(|first_name| !first_name.peek().trim().is_empty()) { - (self.first_name, self.last_name) + (self.first_name.clone(), self.last_name.clone()) } else { (other.first_name.clone(), other.last_name.clone()) }; @@ -66,16 +73,16 @@ impl AddressDetails { Self { first_name, last_name, - city: self.city.or(other.city.clone()), + city: self.city.clone().or(other.city.clone()), country: self.country.or(other.country), - line1: self.line1.or(other.line1.clone()), - line2: self.line2.or(other.line2.clone()), - line3: self.line3.or(other.line3.clone()), - zip: self.zip.or(other.zip.clone()), - state: self.state.or(other.state.clone()), + line1: self.line1.clone().or(other.line1.clone()), + line2: self.line2.clone().or(other.line2.clone()), + line3: self.line3.clone().or(other.line3.clone()), + zip: self.zip.clone().or(other.zip.clone()), + state: self.state.clone().or(other.state.clone()), } } else { - self + self.clone() } } } diff --git a/crates/hyperswitch_domain_models/src/merchant_account.rs b/crates/hyperswitch_domain_models/src/merchant_account.rs index 1e3302dab4a3..a6d2114f0fe9 100644 --- a/crates/hyperswitch_domain_models/src/merchant_account.rs +++ b/crates/hyperswitch_domain_models/src/merchant_account.rs @@ -255,7 +255,6 @@ pub enum MerchantAccountUpdate { } #[cfg(feature = "v1")] - impl From for MerchantAccountUpdateInternal { fn from(merchant_account_update: MerchantAccountUpdate) -> Self { let now = date_time::now(); diff --git a/crates/hyperswitch_domain_models/src/payment_address.rs b/crates/hyperswitch_domain_models/src/payment_address.rs index 548dd0c54166..176bef0c88bb 100644 --- a/crates/hyperswitch_domain_models/src/payment_address.rs +++ b/crates/hyperswitch_domain_models/src/payment_address.rs @@ -1,4 +1,4 @@ -use api_models::payments::Address; +use crate::address::Address; #[derive(Clone, Default, Debug)] pub struct PaymentAddress { diff --git a/crates/hyperswitch_domain_models/src/payment_method_data.rs b/crates/hyperswitch_domain_models/src/payment_method_data.rs index ea994946ca86..820959a59637 100644 --- a/crates/hyperswitch_domain_models/src/payment_method_data.rs +++ b/crates/hyperswitch_domain_models/src/payment_method_data.rs @@ -161,7 +161,6 @@ pub enum PayLaterData { } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize)] - pub enum WalletData { AliPayQr(Box), AliPayRedirect(AliPayRedirection), @@ -234,7 +233,6 @@ pub struct SamsungPayTokenData { } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize)] - pub struct GooglePayWalletData { /// The type of payment method pub pm_type: String, @@ -304,7 +302,6 @@ pub struct MobilePayRedirection {} pub struct MbWayRedirection {} #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize)] - pub struct GooglePayPaymentMethodInfo { /// The name of the card network pub card_network: String, @@ -361,7 +358,6 @@ pub struct ApplepayPaymentMethod { } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] - pub enum RealTimePaymentData { DuitNow {}, Fps {}, @@ -370,7 +366,6 @@ pub enum RealTimePaymentData { } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)] - pub enum BankRedirectData { BancontactCard { card_number: Option, diff --git a/crates/hyperswitch_domain_models/src/payments.rs b/crates/hyperswitch_domain_models/src/payments.rs index 006d78e2f7ab..207668817e36 100644 --- a/crates/hyperswitch_domain_models/src/payments.rs +++ b/crates/hyperswitch_domain_models/src/payments.rs @@ -34,8 +34,8 @@ use self::payment_attempt::PaymentAttempt; use crate::RemoteStorageObject; #[cfg(feature = "v2")] use crate::{ - address::Address, business_profile, errors, merchant_account, payment_method_data, - ApiModelToDieselModelConvertor, + address::Address, business_profile, errors, merchant_account, payment_address, + payment_method_data, ApiModelToDieselModelConvertor, }; #[cfg(feature = "v1")] @@ -582,6 +582,7 @@ where pub payment_intent: PaymentIntent, pub payment_attempt: PaymentAttempt, pub payment_method_data: Option, + pub payment_address: payment_address::PaymentAddress, } #[cfg(feature = "v2")] @@ -593,6 +594,7 @@ where pub flow: PhantomData, pub payment_intent: PaymentIntent, pub payment_attempt: Option, + pub payment_address: payment_address::PaymentAddress, /// Should the payment status be synced with connector /// This will depend on the payment status and the force sync flag in the request pub should_sync_with_connector: bool, diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index 289b1bab37df..591ccc4ff981 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -381,6 +381,17 @@ impl PaymentAttempt { let now = common_utils::date_time::now(); + let payment_method_billing_address = encrypted_data + .payment_method_billing_address + .as_ref() + .map(|data| { + data.clone() + .deserialize_inner_value(|value| value.parse_value("Address")) + }) + .transpose() + .change_context(errors::api_error_response::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to decode billing address")?; + Ok(Self { payment_id: payment_intent.id.clone(), merchant_id: payment_intent.merchant_id.clone(), @@ -423,8 +434,7 @@ impl PaymentAttempt { payment_method_subtype: request.payment_method_subtype, authentication_applied: None, external_reference_id: None, - // TODO: encrypt and store this - payment_method_billing_address: None, + payment_method_billing_address, error: None, connector_mandate_detail: None, id, diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs index c282afa9d0d6..b14e27e8453f 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types.rs @@ -1,6 +1,6 @@ pub mod authentication; pub mod fraud_check; -use api_models::payments::{AdditionalPaymentData, Address, RequestSurchargeDetails}; +use api_models::payments::{AdditionalPaymentData, RequestSurchargeDetails}; use common_utils::{ consts, errors, ext_traits::OptionExt, @@ -15,6 +15,7 @@ use serde_with::serde_as; use super::payment_method_data::PaymentMethodData; use crate::{ + address, errors::api_error_response::ApiErrorResponse, mandates, payments, router_data::{self, RouterData}, @@ -836,7 +837,7 @@ pub struct PaymentsTaxCalculationData { pub currency: storage_enums::Currency, pub shipping_cost: Option, pub order_details: Option>, - pub shipping_address: Address, + pub shipping_address: address::Address, } #[derive(Debug, Clone, Default)] diff --git a/crates/hyperswitch_domain_models/src/router_request_types/authentication.rs b/crates/hyperswitch_domain_models/src/router_request_types/authentication.rs index ab36deb425f5..067c6042ec20 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types/authentication.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types/authentication.rs @@ -4,7 +4,7 @@ use error_stack::{Report, ResultExt}; use serde::{Deserialize, Serialize}; use crate::{ - errors::api_error_response::ApiErrorResponse, payment_method_data::PaymentMethodData, + address, errors::api_error_response::ApiErrorResponse, payment_method_data::PaymentMethodData, router_request_types::BrowserInformation, }; @@ -77,8 +77,8 @@ pub struct PreAuthNRequestData { #[derive(Clone, Debug)] pub struct ConnectorAuthenticationRequestData { pub payment_method_data: PaymentMethodData, - pub billing_address: api_models::payments::Address, - pub shipping_address: Option, + pub billing_address: address::Address, + pub shipping_address: Option, pub browser_details: Option, pub amount: Option, pub currency: Option, diff --git a/crates/hyperswitch_interfaces/src/secrets_interface.rs b/crates/hyperswitch_interfaces/src/secrets_interface.rs index 761981bedda1..6944729191a7 100644 --- a/crates/hyperswitch_interfaces/src/secrets_interface.rs +++ b/crates/hyperswitch_interfaces/src/secrets_interface.rs @@ -10,11 +10,13 @@ use masking::Secret; /// Trait defining the interface for managing application secrets #[async_trait::async_trait] pub trait SecretManagementInterface: Send + Sync { + /* /// Given an input, encrypt/store the secret - // async fn store_secret( - // &self, - // input: Secret, - // ) -> CustomResult; + async fn store_secret( + &self, + input: Secret, + ) -> CustomResult; + */ /// Given an input, decrypt/retrieve the secret async fn get_secret( diff --git a/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs b/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs index d1da6a8c8b68..9573dfa12cb8 100644 --- a/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs +++ b/crates/hyperswitch_interfaces/src/secrets_interface/secret_state.rs @@ -26,17 +26,13 @@ pub struct SecretStateContainer { } impl SecretStateContainer { - /// /// Get the inner data while consuming self - /// #[inline] pub fn into_inner(self) -> T { self.inner } - /// /// Get the reference to inner value - /// #[inline] pub fn get_inner(&self) -> &T { &self.inner diff --git a/crates/kgraph_utils/src/types.rs b/crates/kgraph_utils/src/types.rs index 26f27896e0a5..9ff55b68ab70 100644 --- a/crates/kgraph_utils/src/types.rs +++ b/crates/kgraph_utils/src/types.rs @@ -2,8 +2,8 @@ use std::collections::{HashMap, HashSet}; use api_models::enums as api_enums; use serde::Deserialize; -#[derive(Debug, Deserialize, Clone, Default)] +#[derive(Debug, Deserialize, Clone, Default)] pub struct CountryCurrencyFilter { pub connector_configs: HashMap, pub default_configs: Option, diff --git a/crates/masking/src/abs.rs b/crates/masking/src/abs.rs index f50725d9f234..6501f89c9db0 100644 --- a/crates/masking/src/abs.rs +++ b/crates/masking/src/abs.rs @@ -1,6 +1,4 @@ -//! //! Abstract data types. -//! use crate::Secret; diff --git a/crates/masking/src/boxed.rs b/crates/masking/src/boxed.rs index 67397ec3c07f..42dda0873a13 100644 --- a/crates/masking/src/boxed.rs +++ b/crates/masking/src/boxed.rs @@ -1,4 +1,3 @@ -//! //! `Box` types containing secrets //! //! There is not alias type by design. diff --git a/crates/masking/src/diesel.rs b/crates/masking/src/diesel.rs index ea60a861c9d5..148e50ed823a 100644 --- a/crates/masking/src/diesel.rs +++ b/crates/masking/src/diesel.rs @@ -1,6 +1,4 @@ -//! //! Diesel-related. -//! use diesel::{ backend::Backend, @@ -13,7 +11,7 @@ use diesel::{ use crate::{Secret, Strategy, StrongSecret, ZeroizableSecret}; -impl<'expr, S, I, T> AsExpression for &'expr Secret +impl AsExpression for &Secret where T: sql_types::SingleValue, I: Strategy, @@ -24,7 +22,7 @@ where } } -impl<'expr2, 'expr, S, I, T> AsExpression for &'expr2 &'expr Secret +impl AsExpression for &&Secret where T: sql_types::SingleValue, I: Strategy, @@ -81,7 +79,7 @@ where } } -impl<'expr, S, I, T> AsExpression for &'expr StrongSecret +impl AsExpression for &StrongSecret where T: sql_types::SingleValue, S: ZeroizableSecret, @@ -93,7 +91,7 @@ where } } -impl<'expr2, 'expr, S, I, T> AsExpression for &'expr2 &'expr StrongSecret +impl AsExpression for &&StrongSecret where T: sql_types::SingleValue, S: ZeroizableSecret, diff --git a/crates/masking/src/lib.rs b/crates/masking/src/lib.rs index d376e935bd6e..49e9cbf54f79 100644 --- a/crates/masking/src/lib.rs +++ b/crates/masking/src/lib.rs @@ -2,10 +2,8 @@ #![cfg_attr(docsrs, doc(cfg_hide(doc)))] #![warn(missing_docs)] -//! //! Personal Identifiable Information protection. Wrapper types and traits for secret management which help ensure they aren't accidentally copied, logged, or otherwise exposed (as much as possible), and also ensure secrets are securely wiped from memory when dropped. //! Secret-keeping library inspired by secrecy. -//! #![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR" ), "/", "README.md"))] @@ -49,7 +47,6 @@ pub use crate::serde::{ /// This module should be included with asterisk. /// /// `use masking::prelude::*;` -/// pub mod prelude { pub use super::{ExposeInterface, ExposeOptionInterface, PeekInterface}; } diff --git a/crates/masking/src/maskable.rs b/crates/masking/src/maskable.rs index 7969c9ab8e42..e957e89b3512 100644 --- a/crates/masking/src/maskable.rs +++ b/crates/masking/src/maskable.rs @@ -1,13 +1,9 @@ -//! //! This module contains Masking objects and traits -//! use crate::{ExposeInterface, Secret}; -/// /// An Enum that allows us to optionally mask data, based on which enum variant that data is stored /// in. -/// #[derive(Clone, Eq, PartialEq)] pub enum Maskable { /// Variant which masks the data by wrapping in a Secret @@ -35,9 +31,7 @@ impl std::hash::Hash for Maskable Maskable { - /// /// Get the inner data while consuming self - /// pub fn into_inner(self) -> T { match self { Self::Masked(inner_secret) => inner_secret.expose(), @@ -45,49 +39,37 @@ impl Maskable { } } - /// /// Create a new Masked data - /// pub fn new_masked(item: Secret) -> Self { Self::Masked(item) } - /// /// Create a new non-masked data - /// pub fn new_normal(item: T) -> Self { Self::Normal(item) } - /// /// Checks whether the data is masked. /// Returns `true` if the data is wrapped in the `Masked` variant, /// returns `false` otherwise. - /// pub fn is_masked(&self) -> bool { matches!(self, Self::Masked(_)) } - /// /// Checks whether the data is normal (not masked). /// Returns `true` if the data is wrapped in the `Normal` variant, /// returns `false` otherwise. - /// pub fn is_normal(&self) -> bool { matches!(self, Self::Normal(_)) } } /// Trait for providing a method on custom types for constructing `Maskable` - pub trait Mask { /// The type returned by the `into_masked()` method. Must implement `PartialEq`, `Eq` and `Clone` - type Output: Eq + Clone + PartialEq; - /// /// Construct a `Maskable` instance that wraps `Self::Output` by consuming `self` - /// fn into_masked(self) -> Maskable; } diff --git a/crates/masking/src/secret.rs b/crates/masking/src/secret.rs index a813829d63de..0bd28c3af926 100644 --- a/crates/masking/src/secret.rs +++ b/crates/masking/src/secret.rs @@ -1,12 +1,9 @@ -//! //! Structure describing secret. -//! use std::{fmt, marker::PhantomData}; use crate::{strategy::Strategy, PeekInterface, StrongSecret}; -/// /// Secret thing. /// /// To get access to value use method `expose()` of trait [`crate::ExposeInterface`]. @@ -39,7 +36,6 @@ use crate::{strategy::Strategy, PeekInterface, StrongSecret}; /// /// assert_eq!("hello", &format!("{:?}", my_secret)); /// ``` -/// pub struct Secret where MaskingStrategy: Strategy, diff --git a/crates/masking/src/serde.rs b/crates/masking/src/serde.rs index 0c5782ae04d5..48514df8c6c0 100644 --- a/crates/masking/src/serde.rs +++ b/crates/masking/src/serde.rs @@ -1,6 +1,4 @@ -//! //! Serde-related. -//! pub use erased_serde::Serialize as ErasedSerialize; pub use serde::{de, Deserialize, Serialize, Serializer}; @@ -17,7 +15,6 @@ use crate::{Secret, Strategy, StrongSecret, ZeroizableSecret}; /// /// This is done deliberately to prevent accidental exfiltration of secrets /// via `serde` serialization. -/// #[cfg_attr(docsrs, cfg(feature = "serde"))] pub trait SerializableSecret: Serialize {} @@ -87,7 +84,6 @@ where } } -/// /// Masked serialization. /// /// the default behaviour for secrets is to serialize in exposed format since the common use cases @@ -99,7 +95,6 @@ pub fn masked_serialize(value: &T) -> Result ErasedMaskSerialize for T { } } -impl<'a> Serialize for dyn ErasedMaskSerialize + 'a { +impl Serialize for dyn ErasedMaskSerialize + '_ { fn serialize(&self, serializer: S) -> Result where S: Serializer, @@ -127,7 +122,7 @@ impl<'a> Serialize for dyn ErasedMaskSerialize + 'a { } } -impl<'a> Serialize for dyn ErasedMaskSerialize + 'a + Send { +impl Serialize for dyn ErasedMaskSerialize + '_ + Send { fn serialize(&self, serializer: S) -> Result where S: Serializer, diff --git a/crates/masking/src/string.rs b/crates/masking/src/string.rs index 2638fbd282ef..be6e90a21555 100644 --- a/crates/masking/src/string.rs +++ b/crates/masking/src/string.rs @@ -1,4 +1,3 @@ -//! //! Secret strings //! //! There is not alias type by design. diff --git a/crates/masking/src/strong_secret.rs b/crates/masking/src/strong_secret.rs index 51c0f2cb3fef..300b5463d250 100644 --- a/crates/masking/src/strong_secret.rs +++ b/crates/masking/src/strong_secret.rs @@ -1,6 +1,4 @@ -//! //! Structure describing secret. -//! use std::{fmt, marker::PhantomData}; @@ -9,11 +7,9 @@ use zeroize::{self, Zeroize as ZeroizableSecret}; use crate::{strategy::Strategy, PeekInterface}; -/// /// Secret thing. /// /// To get access to value use method `expose()` of trait [`crate::ExposeInterface`]. -/// pub struct StrongSecret { /// Inner secret value pub(crate) inner_secret: Secret, diff --git a/crates/masking/src/vec.rs b/crates/masking/src/vec.rs index 1f8c1c671e0b..2a077be99439 100644 --- a/crates/masking/src/vec.rs +++ b/crates/masking/src/vec.rs @@ -1,4 +1,3 @@ -//! //! Secret `Vec` types //! //! There is not alias type by design. diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index ed6efea27f83..c7fa29a1b20e 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -575,7 +575,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::routing::RoutingDictionaryRecord, api_models::routing::RoutingKind, api_models::routing::RoutableConnectorChoice, - api_models::routing::SuccessBasedRoutingFeatures, + api_models::routing::DynamicRoutingFeatures, api_models::routing::LinkedRoutingConfigRetrieveResponse, api_models::routing::RoutingRetrieveResponse, api_models::routing::ProfileDefaultRoutingConfig, @@ -586,8 +586,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::routing::StraightThroughAlgorithm, api_models::routing::ConnectorVolumeSplit, api_models::routing::ConnectorSelection, - api_models::routing::ToggleSuccessBasedRoutingQuery, - api_models::routing::ToggleSuccessBasedRoutingPath, + api_models::routing::ToggleDynamicRoutingQuery, + api_models::routing::ToggleDynamicRoutingPath, api_models::routing::ast::RoutableChoiceKind, api_models::enums::RoutableConnectors, api_models::routing::ast::ProgramConnectorSelection, @@ -605,6 +605,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::blocklist::ToggleBlocklistResponse, api_models::blocklist::ListBlocklistQuery, api_models::enums::BlocklistDataKind, + api_models::enums::ErrorCategory, api_models::webhook_events::EventListItemResponse, api_models::webhook_events::EventRetrieveResponse, api_models::webhook_events::OutgoingWebhookRequestContent, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index a756d9fb1b10..2221055be5ab 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -569,6 +569,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::blocklist::ToggleBlocklistResponse, api_models::blocklist::ListBlocklistQuery, api_models::enums::BlocklistDataKind, + api_models::enums::ErrorCategory, api_models::webhook_events::EventListItemResponse, api_models::webhook_events::EventRetrieveResponse, api_models::webhook_events::OutgoingWebhookRequestContent, diff --git a/crates/openapi/src/routes/payments.rs b/crates/openapi/src/routes/payments.rs index 2ffd4f4cdc79..4c9d069a4586 100644 --- a/crates/openapi/src/routes/payments.rs +++ b/crates/openapi/src/routes/payments.rs @@ -549,8 +549,6 @@ pub fn payments_incremental_authorization() {} pub fn payments_external_authentication() {} /// Payments - Complete Authorize -/// -/// #[utoipa::path( post, path = "/{payment_id}/complete_authorize", @@ -569,8 +567,6 @@ pub fn payments_external_authentication() {} pub fn payments_complete_authorize() {} /// Dynamic Tax Calculation -/// -/// #[utoipa::path( post, path = "/payments/{payment_id}/calculate_tax", @@ -587,8 +583,6 @@ pub fn payments_complete_authorize() {} pub fn payments_dynamic_tax_calculation() {} /// Payments - Post Session Tokens -/// -/// #[utoipa::path( post, path = "/payments/{payment_id}/post_session_tokens", diff --git a/crates/openapi/src/routes/routing.rs b/crates/openapi/src/routes/routing.rs index b144fd046ad4..b0fcb75fa49b 100644 --- a/crates/openapi/src/routes/routing.rs +++ b/crates/openapi/src/routes/routing.rs @@ -37,7 +37,7 @@ pub async fn routing_create_config() {} (status = 403, description = "Forbidden"), ), tag = "Routing", - operation_id = "Create a routing algprithm", + operation_id = "Create a routing algorithm", security(("api_key" = []), ("jwt_key" = [])) )] pub async fn routing_create_config() {} @@ -68,7 +68,6 @@ pub async fn routing_link_config() {} /// Routing - Retrieve /// /// Retrieve a routing algorithm - #[utoipa::path( get, path = "/routing/{routing_algorithm_id}", @@ -91,7 +90,6 @@ pub async fn routing_retrieve_config() {} /// Routing - Retrieve /// /// Retrieve a routing algorithm with its algorithm id - #[utoipa::path( get, path = "/v2/routing-algorithm/{id}", @@ -266,7 +264,7 @@ pub async fn routing_update_default_config_for_profile() {} params( ("account_id" = String, Path, description = "Merchant id"), ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"), - ("enable" = SuccessBasedRoutingFeatures, Query, description = "Feature to enable for success based routing"), + ("enable" = DynamicRoutingFeatures, Query, description = "Feature to enable for success based routing"), ), responses( (status = 200, description = "Routing Algorithm created", body = RoutingDictionaryRecord), @@ -277,7 +275,33 @@ pub async fn routing_update_default_config_for_profile() {} (status = 403, description = "Forbidden"), ), tag = "Routing", - operation_id = "Toggle success based dynamic routing algprithm", + operation_id = "Toggle success based dynamic routing algorithm", security(("api_key" = []), ("jwt_key" = [])) )] pub async fn toggle_success_based_routing() {} + +#[cfg(feature = "v1")] +/// Routing - Toggle elimination routing for profile +/// +/// Create a elimination based dynamic routing algorithm +#[utoipa::path( + post, + path = "/account/:account_id/business_profile/:profile_id/dynamic_routing/elimination/toggle", + params( + ("account_id" = String, Path, description = "Merchant id"), + ("profile_id" = String, Path, description = "Profile id under which Dynamic routing needs to be toggled"), + ("enable" = DynamicRoutingFeatures, Query, description = "Feature to enable for success based routing"), + ), + responses( + (status = 200, description = "Routing Algorithm 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 = "Toggle elimination routing algorithm", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn toggle_elimination_routing() {} diff --git a/crates/pm_auth/src/connector/plaid/transformers.rs b/crates/pm_auth/src/connector/plaid/transformers.rs index a91aa57a1e43..a10ff0d60e5c 100644 --- a/crates/pm_auth/src/connector/plaid/transformers.rs +++ b/crates/pm_auth/src/connector/plaid/transformers.rs @@ -20,7 +20,6 @@ pub struct PlaidLinkTokenRequest { } #[derive(Debug, Serialize, Eq, PartialEq)] - pub struct User { pub client_user_id: id_type::CustomerId, } @@ -94,7 +93,6 @@ pub struct PlaidExchangeTokenRequest { } #[derive(Debug, Deserialize, Eq, PartialEq)] - pub struct PlaidExchangeTokenResponse { pub access_token: String, } @@ -236,7 +234,6 @@ pub struct PlaidBankAccountCredentialsRequest { } #[derive(Debug, Deserialize, PartialEq)] - pub struct PlaidBankAccountCredentialsResponse { pub accounts: Vec, pub numbers: PlaidBankAccountCredentialsNumbers, @@ -251,7 +248,6 @@ pub struct BankAccountCredentialsOptions { } #[derive(Debug, Deserialize, PartialEq)] - pub struct PlaidBankAccountCredentialsAccounts { pub account_id: String, pub name: String, diff --git a/crates/redis_interface/src/commands.rs b/crates/redis_interface/src/commands.rs index 9fd07a473d4a..746b424abc88 100644 --- a/crates/redis_interface/src/commands.rs +++ b/crates/redis_interface/src/commands.rs @@ -3,8 +3,6 @@ //! The folder provides generic functions for providing serialization //! and deserialization while calling redis. //! It also includes instruments to provide tracing. -//! -//! use std::fmt::Debug; diff --git a/crates/redis_interface/src/errors.rs b/crates/redis_interface/src/errors.rs index 0e2a4b8d63b0..9e0fb4639a5d 100644 --- a/crates/redis_interface/src/errors.rs +++ b/crates/redis_interface/src/errors.rs @@ -1,6 +1,4 @@ -//! //! Errors specific to this custom redis interface -//! #[derive(Debug, thiserror::Error, PartialEq)] pub enum RedisError { diff --git a/crates/redis_interface/src/types.rs b/crates/redis_interface/src/types.rs index f40b81af68e2..92429f617d13 100644 --- a/crates/redis_interface/src/types.rs +++ b/crates/redis_interface/src/types.rs @@ -1,7 +1,5 @@ -//! //! Data types and type conversions //! from `fred`'s internal data-types to custom data-types -//! use common_utils::errors::CustomResult; use fred::types::RedisValue as FredRedisValue; diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index f6e1f0efc69f..dde06fe832fc 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -91,7 +91,6 @@ rdkafka = "0.36.2" regex = "1.10.4" reqwest = { version = "0.11.27", features = ["json", "rustls-tls", "gzip", "multipart"] } ring = "0.17.8" -roxmltree = "0.19.0" rust_decimal = { version = "1.35.0", features = ["serde-with-float", "serde-with-str"] } rust-i18n = { git = "https://github.com/kashif-m/rust-i18n", rev = "f2d8096aaaff7a87a847c35a5394c269f75e077a" } rustc-hash = "1.1.0" diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index 55516eeb3bcf..545c058ce1cd 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -321,9 +321,10 @@ impl TryFrom for payments::PaymentsRequest { let billing = pmd.billing_details.clone().map(payments::Address::from); let payment_method_data = match pmd.payment_method_details.as_ref() { Some(spmd) => Some(payments::PaymentMethodData::from(spmd.to_owned())), - None => { - get_pmd_based_on_payment_method_type(item.payment_method_types, billing.clone()) - } + None => get_pmd_based_on_payment_method_type( + item.payment_method_types, + billing.clone().map(From::from), + ), }; payments::PaymentMethodDataRequest { @@ -911,7 +912,7 @@ pub struct StripePaymentRetrieveBody { //To handle payment types that have empty payment method data fn get_pmd_based_on_payment_method_type( payment_method_type: Option, - billing_details: Option, + billing_details: Option, ) -> Option { match payment_method_type { Some(api_enums::PaymentMethodType::UpiIntent) => Some(payments::PaymentMethodData::Upi( diff --git a/crates/router/src/configs/defaults/payment_connector_required_fields.rs b/crates/router/src/configs/defaults/payment_connector_required_fields.rs index d359335bf128..c759b724414a 100644 --- a/crates/router/src/configs/defaults/payment_connector_required_fields.rs +++ b/crates/router/src/configs/defaults/payment_connector_required_fields.rs @@ -1952,6 +1952,98 @@ impl Default for settings::RequiredFields { ), } ), + ( + enums::Connector::Nexixpay, + RequiredFieldFinal { + mandate: HashMap::new(), + non_mandate: HashMap::new(), + common: HashMap::from( + [ + ( + "payment_method_data.card.card_number".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_number".to_string(), + display_name: "card_number".to_string(), + field_type: enums::FieldType::UserCardNumber, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_month".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_month".to_string(), + display_name: "card_exp_month".to_string(), + field_type: enums::FieldType::UserCardExpiryMonth, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_year".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_year".to_string(), + display_name: "card_exp_year".to_string(), + field_type: enums::FieldType::UserCardExpiryYear, + value: None, + } + ), + ( + "billing.address.line1".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.line1".to_string(), + display_name: "line1".to_string(), + field_type: enums::FieldType::UserAddressLine1, + value: None, + } + ), + ( + "billing.address.line2".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.line2".to_string(), + display_name: "line1".to_string(), + field_type: enums::FieldType::UserAddressLine2, + value: None, + } + ), + ( + "billing.address.city".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.city".to_string(), + display_name: "city".to_string(), + field_type: enums::FieldType::UserAddressCity, + value: None, + } + ), + ( + "billing.address.zip".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.zip".to_string(), + display_name: "zip".to_string(), + field_type: enums::FieldType::UserAddressPincode, + value: None, + } + ), + ( + "billing.address.first_name".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.first_name".to_string(), + display_name: "first_name".to_string(), + field_type: enums::FieldType::UserFullName, + value: None, + } + ), + ( + "billing.address.last_name".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.billing.address.last_name".to_string(), + display_name: "last_name".to_string(), + field_type: enums::FieldType::UserFullName, + value: None, + } + ) + ] + ), + } + ), ( enums::Connector::Nmi, RequiredFieldFinal { @@ -11529,18 +11621,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.ach.account_number".to_string(), + "payment_method_data.bank_debit.ach_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.ach.account_number".to_string(), + required_field: "payment_method_data.bank_debit.ach_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.ach.routing_number".to_string(), + "payment_method_data.bank_debit.ach_bank_debit.routing_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.ach.routing_number".to_string(), + required_field: "payment_method_data.bank_debit.ach_bank_debit.routing_number".to_string(), display_name: "bank_routing_number".to_string(), field_type: enums::FieldType::Text, value: None, @@ -11571,18 +11663,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.ach.account_number".to_string(), + "payment_method_data.bank_debit.ach_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.ach.account_number".to_string(), + required_field: "payment_method_data.bank_debit.ach_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.ach.routing_number".to_string(), + "payment_method_data.bank_debit.ach_bank_debit.routing_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.ach.routing_number".to_string(), + required_field: "payment_method_data.bank_debit.ach_bank_debit.routing_number".to_string(), display_name: "bank_routing_number".to_string(), field_type: enums::FieldType::Text, value: None, @@ -11740,18 +11832,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.bacs.account_number".to_string(), + "payment_method_data.bank_debit.bacs_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.account_number".to_string(), + required_field: "payment_method_data.bank_debit.bacs_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.bacs.sort_code".to_string(), + "payment_method_data.bank_debit.bacs_bank_debit.sort_code".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.sort_code".to_string(), + required_field: "payment_method_data.bank_debit.bacs_bank_debit.sort_code".to_string(), display_name: "bank_sort_code".to_string(), field_type: enums::FieldType::Text, value: None, @@ -11812,18 +11904,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.bacs.account_number".to_string(), + "payment_method_data.bank_debit.bacs_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.account_number".to_string(), + required_field: "payment_method_data.bank_debit.bacs_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.bacs.sort_code".to_string(), + "payment_method_data.bank_debit.bacs_bank_debit.sort_code".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.sort_code".to_string(), + required_field: "payment_method_data.bank_debit.bacs_bank_debit.sort_code".to_string(), display_name: "bank_sort_code".to_string(), field_type: enums::FieldType::Text, value: None, @@ -11862,18 +11954,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.becs.account_number".to_string(), + "payment_method_data.bank_debit.becs_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.becs.account_number".to_string(), + required_field: "payment_method_data.bank_debit.becs_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.becs.bsb_number".to_string(), + "payment_method_data.bank_debit.becs_bank_debit.bsb_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.becs.bsb_number".to_string(), + required_field: "payment_method_data.bank_debit.becs_bank_debit.bsb_number".to_string(), display_name: "bsb_number".to_string(), field_type: enums::FieldType::Text, value: None, @@ -11914,18 +12006,18 @@ impl Default for settings::RequiredFields { } ), ( - "payment_method_data.bank_debit.bacs.account_number".to_string(), + "payment_method_data.bank_debit.becs_bank_debit.account_number".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.account_number".to_string(), + required_field: "payment_method_data.bank_debit.becs_bank_debit.account_number".to_string(), display_name: "bank_account_number".to_string(), field_type: enums::FieldType::UserBankAccountNumber, value: None, } ), ( - "payment_method_data.bank_debit.bacs.sort_code".to_string(), + "payment_method_data.bank_debit.becs_bank_debit.sort_code".to_string(), RequiredFieldInfo { - required_field: "payment_method_data.bank_debit.bacs.sort_code".to_string(), + required_field: "payment_method_data.bank_debit.becs_bank_debit.sort_code".to_string(), display_name: "bank_sort_code".to_string(), field_type: enums::FieldType::Text, value: None, diff --git a/crates/router/src/configs/secrets_transformers.rs b/crates/router/src/configs/secrets_transformers.rs index dbdba189ed19..3ab56266b555 100644 --- a/crates/router/src/configs/secrets_transformers.rs +++ b/crates/router/src/configs/secrets_transformers.rs @@ -545,5 +545,6 @@ pub(crate) async fn fetch_raw_secrets( .network_tokenization_supported_card_networks, network_tokenization_service, network_tokenization_supported_connectors: conf.network_tokenization_supported_connectors, + theme_storage: conf.theme_storage, } } diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index 4e559a261b9e..1da4a33f5f33 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -128,6 +128,7 @@ pub struct Settings { pub network_tokenization_supported_card_networks: NetworkTokenizationSupportedCardNetworks, pub network_tokenization_service: Option>, pub network_tokenization_supported_connectors: NetworkTokenizationSupportedConnectors, + pub theme_storage: FileStorageConfig, } #[derive(Debug, Deserialize, Clone, Default)] @@ -886,6 +887,10 @@ impl Settings { .validate() .map_err(|err| ApplicationError::InvalidConfigurationValueError(err.into()))?; + self.theme_storage + .validate() + .map_err(|err| ApplicationError::InvalidConfigurationValueError(err.to_string()))?; + Ok(()) } } diff --git a/crates/router/src/connector.rs b/crates/router/src/connector.rs index 5874f4ba463b..1f67c1f75d76 100644 --- a/crates/router/src/connector.rs +++ b/crates/router/src/connector.rs @@ -2,10 +2,8 @@ pub mod aci; pub mod adyen; pub mod adyenplatform; pub mod authorizedotnet; -pub mod bamboraapac; pub mod bankofamerica; pub mod bluesnap; -pub mod boku; pub mod braintree; pub mod checkout; pub mod cybersource; @@ -14,7 +12,6 @@ pub mod datatrans; pub mod dummyconnector; pub mod ebanx; pub mod globalpay; -pub mod gocardless; pub mod gpayments; pub mod iatapay; pub mod itaubank; @@ -32,8 +29,6 @@ pub mod payone; pub mod paypal; pub mod placetopay; pub mod plaid; -pub mod prophetpay; -pub mod rapyd; pub mod riskified; pub mod signifyd; pub mod stripe; @@ -46,32 +41,32 @@ pub mod wise; pub use hyperswitch_connectors::connectors::{ airwallex, airwallex::Airwallex, amazonpay, amazonpay::Amazonpay, bambora, bambora::Bambora, - billwerk, billwerk::Billwerk, bitpay, bitpay::Bitpay, cashtocode, cashtocode::Cashtocode, - coinbase, coinbase::Coinbase, cryptopay, cryptopay::Cryptopay, deutschebank, - deutschebank::Deutschebank, digitalvirgo, digitalvirgo::Digitalvirgo, dlocal, dlocal::Dlocal, - elavon, elavon::Elavon, fiserv, fiserv::Fiserv, fiservemea, fiservemea::Fiservemea, fiuu, - fiuu::Fiuu, forte, forte::Forte, globepay, globepay::Globepay, helcim, helcim::Helcim, inespay, - inespay::Inespay, jpmorgan, jpmorgan::Jpmorgan, mollie, mollie::Mollie, multisafepay, + bamboraapac, bamboraapac::Bamboraapac, billwerk, billwerk::Billwerk, bitpay, bitpay::Bitpay, + boku, boku::Boku, cashtocode, cashtocode::Cashtocode, coinbase, coinbase::Coinbase, cryptopay, + cryptopay::Cryptopay, deutschebank, deutschebank::Deutschebank, digitalvirgo, + digitalvirgo::Digitalvirgo, dlocal, dlocal::Dlocal, elavon, elavon::Elavon, fiserv, + fiserv::Fiserv, fiservemea, fiservemea::Fiservemea, fiuu, fiuu::Fiuu, forte, forte::Forte, + globepay, globepay::Globepay, gocardless, gocardless::Gocardless, helcim, helcim::Helcim, + inespay, inespay::Inespay, jpmorgan, jpmorgan::Jpmorgan, mollie, mollie::Mollie, multisafepay, multisafepay::Multisafepay, nexinets, nexinets::Nexinets, nexixpay, nexixpay::Nexixpay, nomupay, nomupay::Nomupay, novalnet, novalnet::Novalnet, payeezy, payeezy::Payeezy, payu, - payu::Payu, powertranz, powertranz::Powertranz, razorpay, razorpay::Razorpay, redsys, - redsys::Redsys, shift4, shift4::Shift4, square, square::Square, stax, stax::Stax, taxjar, - taxjar::Taxjar, thunes, thunes::Thunes, tsys, tsys::Tsys, volt, volt::Volt, worldline, - worldline::Worldline, worldpay, worldpay::Worldpay, xendit, xendit::Xendit, zen, zen::Zen, zsl, - zsl::Zsl, + payu::Payu, powertranz, powertranz::Powertranz, prophetpay, prophetpay::Prophetpay, rapyd, + rapyd::Rapyd, razorpay, razorpay::Razorpay, redsys, redsys::Redsys, shift4, shift4::Shift4, + square, square::Square, stax, stax::Stax, taxjar, taxjar::Taxjar, thunes, thunes::Thunes, tsys, + tsys::Tsys, volt, volt::Volt, worldline, worldline::Worldline, worldpay, worldpay::Worldpay, + xendit, xendit::Xendit, zen, zen::Zen, zsl, zsl::Zsl, }; #[cfg(feature = "dummy_connector")] pub use self::dummyconnector::DummyConnector; pub use self::{ aci::Aci, adyen::Adyen, adyenplatform::Adyenplatform, authorizedotnet::Authorizedotnet, - bamboraapac::Bamboraapac, bankofamerica::Bankofamerica, bluesnap::Bluesnap, boku::Boku, - braintree::Braintree, checkout::Checkout, cybersource::Cybersource, datatrans::Datatrans, - ebanx::Ebanx, globalpay::Globalpay, gocardless::Gocardless, gpayments::Gpayments, - iatapay::Iatapay, itaubank::Itaubank, klarna::Klarna, mifinity::Mifinity, netcetera::Netcetera, - nmi::Nmi, noon::Noon, nuvei::Nuvei, opayo::Opayo, opennode::Opennode, paybox::Paybox, - payme::Payme, payone::Payone, paypal::Paypal, placetopay::Placetopay, plaid::Plaid, - prophetpay::Prophetpay, rapyd::Rapyd, riskified::Riskified, signifyd::Signifyd, stripe::Stripe, + bankofamerica::Bankofamerica, bluesnap::Bluesnap, braintree::Braintree, checkout::Checkout, + cybersource::Cybersource, datatrans::Datatrans, ebanx::Ebanx, globalpay::Globalpay, + gpayments::Gpayments, iatapay::Iatapay, itaubank::Itaubank, klarna::Klarna, mifinity::Mifinity, + netcetera::Netcetera, nmi::Nmi, noon::Noon, nuvei::Nuvei, opayo::Opayo, opennode::Opennode, + paybox::Paybox, payme::Payme, payone::Payone, paypal::Paypal, placetopay::Placetopay, + plaid::Plaid, riskified::Riskified, signifyd::Signifyd, stripe::Stripe, threedsecureio::Threedsecureio, trustpay::Trustpay, wellsfargo::Wellsfargo, wellsfargopayout::Wellsfargopayout, wise::Wise, }; diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs index f3b7414a923a..57b80f58153e 100644 --- a/crates/router/src/connector/adyen.rs +++ b/crates/router/src/connector/adyen.rs @@ -1908,6 +1908,27 @@ impl api::IncomingWebhook for Adyen { updated_at: notif.event_date, }) } + + fn get_mandate_details( + &self, + request: &api::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult< + Option, + errors::ConnectorError, + > { + let notif = get_webhook_object_from_body(request.body) + .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?; + let mandate_reference = + notif + .additional_data + .recurring_detail_reference + .map(|mandate_id| { + hyperswitch_domain_models::router_flow_types::ConnectorMandateDetails { + connector_mandate_id: mandate_id.clone(), + } + }); + Ok(mandate_reference) + } } impl api::Dispute for Adyen {} diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 12cef3aa9f78..5309f5fa76c8 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -1448,7 +1448,7 @@ pub enum OpenBankingUKIssuer { pub struct AdyenTestBankNames<'a>(&'a str); -impl<'a> TryFrom<&common_enums::BankNames> for AdyenTestBankNames<'a> { +impl TryFrom<&common_enums::BankNames> for AdyenTestBankNames<'_> { type Error = Error; fn try_from(bank: &common_enums::BankNames) -> Result { Ok(match bank { @@ -1501,7 +1501,7 @@ impl<'a> TryFrom<&common_enums::BankNames> for AdyenTestBankNames<'a> { pub struct AdyenBankNames<'a>(&'a str); -impl<'a> TryFrom<&common_enums::BankNames> for AdyenBankNames<'a> { +impl TryFrom<&common_enums::BankNames> for AdyenBankNames<'_> { type Error = Error; fn try_from(bank: &common_enums::BankNames) -> Result { Ok(match bank { @@ -1550,9 +1550,7 @@ impl TryFrom<&types::ConnectorAuthType> for AdyenAuthType { } } -impl<'a> TryFrom<&AdyenRouterData<&types::PaymentsAuthorizeRouterData>> - for AdyenPaymentRequest<'a> -{ +impl TryFrom<&AdyenRouterData<&types::PaymentsAuthorizeRouterData>> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( item: &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, @@ -1612,7 +1610,7 @@ impl<'a> TryFrom<&AdyenRouterData<&types::PaymentsAuthorizeRouterData>> } } -impl<'a> TryFrom<&types::PaymentsPreProcessingRouterData> for AdyenBalanceRequest<'a> { +impl TryFrom<&types::PaymentsPreProcessingRouterData> for AdyenBalanceRequest<'_> { type Error = Error; fn try_from(item: &types::PaymentsPreProcessingRouterData) -> Result { let payment_method = match &item.request.payment_method_data { @@ -1757,7 +1755,7 @@ fn get_amount_data(item: &AdyenRouterData<&types::PaymentsAuthorizeRouterData>) } pub fn get_address_info( - address: Option<&payments::Address>, + address: Option<&hyperswitch_domain_models::address::Address>, ) -> Option>> { address.and_then(|add| { add.address.as_ref().map( @@ -1819,7 +1817,9 @@ fn get_telephone_number(item: &types::PaymentsAuthorizeRouterData) -> Option) -> Option { +fn get_shopper_name( + address: Option<&hyperswitch_domain_models::address::Address>, +) -> Option { let billing = address.and_then(|billing| billing.address.as_ref()); Some(ShopperName { first_name: billing.and_then(|a| a.first_name.clone()), @@ -1827,7 +1827,9 @@ fn get_shopper_name(address: Option<&payments::Address>) -> Option }) } -fn get_country_code(address: Option<&payments::Address>) -> Option { +fn get_country_code( + address: Option<&hyperswitch_domain_models::address::Address>, +) -> Option { address.and_then(|billing| billing.address.as_ref().and_then(|address| address.country)) } @@ -1863,8 +1865,8 @@ fn build_shopper_reference( }) } -impl<'a> TryFrom<(&domain::BankDebitData, &types::PaymentsAuthorizeRouterData)> - for AdyenPaymentMethod<'a> +impl TryFrom<(&domain::BankDebitData, &types::PaymentsAuthorizeRouterData)> + for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -1911,8 +1913,8 @@ impl<'a> TryFrom<(&domain::BankDebitData, &types::PaymentsAuthorizeRouterData)> } } -impl<'a> TryFrom<(&domain::VoucherData, &types::PaymentsAuthorizeRouterData)> - for AdyenPaymentMethod<'a> +impl TryFrom<(&domain::VoucherData, &types::PaymentsAuthorizeRouterData)> + for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -1958,7 +1960,7 @@ impl<'a> TryFrom<(&domain::VoucherData, &types::PaymentsAuthorizeRouterData)> } } -impl<'a> TryFrom<&domain::GiftCardData> for AdyenPaymentMethod<'a> { +impl TryFrom<&domain::GiftCardData> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from(gift_card_data: &domain::GiftCardData) -> Result { match gift_card_data { @@ -1992,7 +1994,7 @@ fn get_adyen_card_network(card_network: common_enums::CardNetwork) -> Option TryFrom<(&domain::Card, Option>)> for AdyenPaymentMethod<'a> { +impl TryFrom<(&domain::Card, Option>)> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( (card, card_holder_name): (&domain::Card, Option>), @@ -2068,8 +2070,8 @@ impl TryFrom<&utils::CardIssuer> for CardBrand { } } -impl<'a> TryFrom<(&domain::WalletData, &types::PaymentsAuthorizeRouterData)> - for AdyenPaymentMethod<'a> +impl TryFrom<(&domain::WalletData, &types::PaymentsAuthorizeRouterData)> + for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -2206,7 +2208,7 @@ pub fn check_required_field<'a, T>( }) } -impl<'a> +impl TryFrom<( &domain::PayLaterData, &Option, @@ -2216,7 +2218,7 @@ impl<'a> &Option>, &Option
, &Option
, - )> for AdyenPaymentMethod<'a> + )> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -2329,12 +2331,12 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &domain::BankRedirectData, Option, &types::PaymentsAuthorizeRouterData, - )> for AdyenPaymentMethod<'a> + )> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -2492,11 +2494,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &domain::BankTransferData, &types::PaymentsAuthorizeRouterData, - )> for AdyenPaymentMethod<'a> + )> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( @@ -2564,7 +2566,7 @@ fn get_optional_shopper_email(item: &types::PaymentsAuthorizeRouterData) -> Opti } } -impl<'a> TryFrom<&domain::payments::CardRedirectData> for AdyenPaymentMethod<'a> { +impl TryFrom<&domain::payments::CardRedirectData> for AdyenPaymentMethod<'_> { type Error = Error; fn try_from( card_redirect_data: &domain::payments::CardRedirectData, @@ -2583,11 +2585,11 @@ impl<'a> TryFrom<&domain::payments::CardRedirectData> for AdyenPaymentMethod<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, payments::MandateReferenceId, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -2719,11 +2721,11 @@ impl<'a> }) } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::Card, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -2784,11 +2786,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::BankDebitData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; @@ -2842,11 +2844,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::VoucherData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; @@ -2903,11 +2905,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::BankTransferData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; @@ -2956,11 +2958,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::GiftCardData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; @@ -3009,11 +3011,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::BankRedirectData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -3117,11 +3119,11 @@ fn get_shopper_email( } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::WalletData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -3192,11 +3194,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::PayLaterData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -3268,11 +3270,11 @@ impl<'a> } } -impl<'a> +impl TryFrom<( &AdyenRouterData<&types::PaymentsAuthorizeRouterData>, &domain::payments::CardRedirectData, - )> for AdyenPaymentRequest<'a> + )> for AdyenPaymentRequest<'_> { type Error = Error; fn try_from( @@ -4263,6 +4265,9 @@ pub struct AdyenAdditionalDataWH { pub chargeback_reason_code: Option, #[serde(default, with = "common_utils::custom_serde::iso8601::option")] pub defense_period_ends_at: Option, + /// Enable recurring details in dashboard to receive this ID, https://docs.adyen.com/online-payments/tokenization/create-and-use-tokens#test-and-go-live + #[serde(rename = "recurring.recurringDetailReference")] + pub recurring_detail_reference: Option>, } #[derive(Debug, Deserialize)] @@ -4862,7 +4867,7 @@ impl TryFrom<&AdyenRouterData<&types::PayoutsRouterData>> for AdyenPayoutC })?, }; let bank_data = PayoutBankData { bank: bank_details }; - let address: &payments::AddressDetails = item.router_data.get_billing_address()?; + let address = item.router_data.get_billing_address()?; Ok(Self { amount: Amount { value: item.amount.to_owned(), @@ -4904,7 +4909,7 @@ impl TryFrom<&AdyenRouterData<&types::PayoutsRouterData>> for AdyenPayoutC })? } }; - let address: &payments::AddressDetails = item.router_data.get_billing_address()?; + let address = item.router_data.get_billing_address()?; let payout_wallet = PayoutWalletData { selected_brand: PayoutBrand::Paypal, additional_data, @@ -5098,7 +5103,6 @@ impl TryFrom<&types::DefendDisputeRouterData> for AdyenDefendDisputeRequest { #[derive(Default, Debug, Serialize)] #[serde(rename_all = "camelCase")] - pub struct Evidence { defense_documents: Vec, merchant_account_code: Secret, @@ -5107,7 +5111,6 @@ pub struct Evidence { #[derive(Default, Debug, Serialize)] #[serde(rename_all = "camelCase")] - pub struct DefenseDocuments { content: Secret, content_type: Option, diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 1530cbd82f83..71cc006700e4 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -1,4 +1,3 @@ -use api_models::payments; use base64::Engine; use common_utils::pii; use masking::{ExposeInterface, PeekInterface, Secret}; @@ -494,7 +493,7 @@ impl // } fn build_bill_to( - address_details: Option<&payments::Address>, + address_details: Option<&hyperswitch_domain_models::address::Address>, email: pii::Email, ) -> Result> { let default_address = BillTo { diff --git a/crates/router/src/connector/bluesnap/transformers.rs b/crates/router/src/connector/bluesnap/transformers.rs index 022512ea1c19..d3fc0779e255 100644 --- a/crates/router/src/connector/bluesnap/transformers.rs +++ b/crates/router/src/connector/bluesnap/transformers.rs @@ -1125,7 +1125,7 @@ pub enum BluesnapErrors { } fn get_card_holder_info( - address: &api::AddressDetails, + address: &hyperswitch_domain_models::address::AddressDetails, email: Email, ) -> CustomResult, errors::ConnectorError> { let first_name = address.get_first_name()?; diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs index 24c6118e44a8..00624ce0f9b1 100644 --- a/crates/router/src/connector/braintree/transformers.rs +++ b/crates/router/src/connector/braintree/transformers.rs @@ -67,13 +67,11 @@ pub struct GenericVariableInput { #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] - pub struct BraintreeApiErrorResponse { pub api_error_response: ApiErrorResponse, } #[derive(Debug, Deserialize, Serialize)] - pub struct ErrorsObject { pub errors: Vec, @@ -82,7 +80,6 @@ pub struct ErrorsObject { #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] - pub struct TransactionError { pub errors: Vec, pub credit_card: Option, @@ -122,7 +119,6 @@ pub struct BraintreeErrorResponse { #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] #[serde(untagged)] - pub enum ErrorResponses { BraintreeApiErrorResponse(Box), BraintreeErrorResponse(Box), @@ -907,7 +903,6 @@ pub struct BraintreeRefundResponseData { } #[derive(Debug, Clone, Deserialize, Serialize)] - pub struct RefundResponse { pub data: BraintreeRefundResponseData, } diff --git a/crates/router/src/connector/cybersource.rs b/crates/router/src/connector/cybersource.rs index 806cf67b2da2..06f448e075a9 100644 --- a/crates/router/src/connector/cybersource.rs +++ b/crates/router/src/connector/cybersource.rs @@ -1,9 +1,10 @@ pub mod transformers; -use std::fmt::Debug; - use base64::Engine; -use common_utils::request::RequestContent; +use common_utils::{ + request::RequestContent, + types::{AmountConvertor, MinorUnit, StringMajorUnit, StringMajorUnitForConnector}, +}; use diesel_models::enums; use error_stack::{report, Report, ResultExt}; use masking::{ExposeInterface, PeekInterface}; @@ -12,7 +13,7 @@ use time::OffsetDateTime; use transformers as cybersource; use url::Url; -use super::utils::{PaymentsAuthorizeRequestData, RouterData}; +use super::utils::{convert_amount, PaymentsAuthorizeRequestData, RouterData}; use crate::{ configs::settings, connector::{ @@ -36,9 +37,18 @@ use crate::{ utils::BytesExt, }; -#[derive(Debug, Clone)] -pub struct Cybersource; +#[derive(Clone)] +pub struct Cybersource { + amount_converter: &'static (dyn AmountConvertor + Sync), +} +impl Cybersource { + pub fn new() -> &'static Self { + &Self { + amount_converter: &StringMajorUnitForConnector, + } + } +} impl Cybersource { pub fn generate_digest(&self, payload: &[u8]) -> String { let payload_digest = digest::digest(&digest::SHA256, payload); @@ -617,20 +627,20 @@ impl req: &types::PaymentsPreProcessingRouterData, _connectors: &settings::Connectors, ) -> CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let minor_amount = req.request - .currency + .minor_amount .ok_or(errors::ConnectorError::MissingRequiredField { - field_name: "currency", - })?, + field_name: "minor_amount", + })?; + let currency = req.request - .amount + .currency .ok_or(errors::ConnectorError::MissingRequiredField { - field_name: "amount", - })?, - req, - ))?; + field_name: "currency", + })?; + let amount = convert_amount(self.amount_converter, minor_amount, currency)?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); let connector_req = cybersource::CybersourcePreProcessingRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -718,12 +728,12 @@ impl ConnectorIntegration CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let amount = convert_amount( + self.amount_converter, + req.request.minor_amount_to_capture, req.request.currency, - req.request.amount_to_capture, - req, - ))?; + )?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); let connector_req = cybersource::CybersourcePaymentsCaptureRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -922,12 +932,12 @@ impl ConnectorIntegration CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let amount = convert_amount( + self.amount_converter, + req.request.minor_amount, req.request.currency, - req.request.amount, - req, - ))?; + )?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); if req.is_three_ds() && req.request.is_card() && (req.request.connector_mandate_id().is_none() @@ -1068,12 +1078,12 @@ impl ConnectorIntegration, _connectors: &settings::Connectors, ) -> CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let amount = convert_amount( + self.amount_converter, + req.request.minor_amount, req.request.destination_currency, - req.request.amount, - req, - ))?; + )?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); let connector_req = cybersource::CybersourcePayoutFulfillRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -1193,12 +1203,12 @@ impl req: &types::PaymentsCompleteAuthorizeRouterData, _connectors: &settings::Connectors, ) -> CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let amount = convert_amount( + self.amount_converter, + req.request.minor_amount, req.request.currency, - req.request.amount, - req, - ))?; + )?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); let connector_req = cybersource::CybersourcePaymentsRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -1317,20 +1327,21 @@ impl ConnectorIntegration CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let minor_amount = req.request - .currency + .minor_amount .ok_or(errors::ConnectorError::MissingRequiredField { - field_name: "Currency", - })?, + field_name: "Amount", + })?; + let currency = req.request - .amount + .currency .ok_or(errors::ConnectorError::MissingRequiredField { - field_name: "Amount", - })?, - req, - ))?; + field_name: "Currency", + })?; + let amount = convert_amount(self.amount_converter, minor_amount, currency)?; + let connector_router_data = cybersource::CybersourceRouterData::from((amount, req)); + let connector_req = cybersource::CybersourceVoidRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -1443,12 +1454,12 @@ impl ConnectorIntegration CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let refund_amount = convert_amount( + self.amount_converter, + req.request.minor_refund_amount, req.request.currency, - req.request.refund_amount, - req, - ))?; + )?; + let connector_router_data = cybersource::CybersourceRouterData::from((refund_amount, req)); let connector_req = cybersource::CybersourceRefundRequest::try_from(&connector_router_data)?; Ok(RequestContent::Json(Box::new(connector_req))) @@ -1609,12 +1620,14 @@ impl req: &types::PaymentsIncrementalAuthorizationRouterData, _connectors: &settings::Connectors, ) -> CustomResult { - let connector_router_data = cybersource::CybersourceRouterData::try_from(( - &self.get_currency_unit(), + let minor_additional_amount = MinorUnit::new(req.request.additional_amount); + let additional_amount = convert_amount( + self.amount_converter, + minor_additional_amount, req.request.currency, - req.request.additional_amount, - req, - ))?; + )?; + let connector_router_data = + cybersource::CybersourceRouterData::from((additional_amount, req)); let connector_request = cybersource::CybersourcePaymentsIncrementalAuthorizationRequest::try_from( &connector_router_data, diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index 2ea36e3e35e5..7ce98d3d5a34 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -1,17 +1,16 @@ use api_models::payments; #[cfg(feature = "payouts")] -use api_models::{ - payments::{AddressDetails, PhoneDetails}, - payouts::PayoutMethodData, -}; +use api_models::payouts::PayoutMethodData; use base64::Engine; use common_enums::FutureUsage; use common_utils::{ ext_traits::{OptionExt, ValueExt}, pii, - types::SemanticVersion, + types::{SemanticVersion, StringMajorUnit}, }; use error_stack::ResultExt; +#[cfg(feature = "payouts")] +use hyperswitch_domain_models::address::{AddressDetails, PhoneDetails}; use masking::{ExposeInterface, PeekInterface, Secret}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -41,21 +40,16 @@ use crate::{ #[derive(Debug, Serialize)] pub struct CybersourceRouterData { - pub amount: String, + pub amount: StringMajorUnit, pub router_data: T, } -impl TryFrom<(&api::CurrencyUnit, enums::Currency, i64, T)> for CybersourceRouterData { - type Error = error_stack::Report; - fn try_from( - (currency_unit, currency, amount, item): (&api::CurrencyUnit, enums::Currency, i64, T), - ) -> Result { - // This conversion function is used at different places in the file, if updating this, keep a check for those - let amount = utils::get_amount_as_string(currency_unit, amount, currency)?; - Ok(Self { +impl From<(StringMajorUnit, T)> for CybersourceRouterData { + fn from((amount, router_data): (StringMajorUnit, T)) -> Self { + Self { amount, - router_data: item, - }) + router_data, + } } } @@ -93,7 +87,7 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest { let order_information = OrderInformationWithBill { amount_details: Amount { - total_amount: "0".to_string(), + total_amount: StringMajorUnit::zero(), currency: item.request.currency, }, bill_to: Some(bill_to), @@ -526,14 +520,14 @@ pub struct OrderInformation { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct Amount { - total_amount: String, + total_amount: StringMajorUnit, currency: api_models::enums::Currency, } #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct AdditionalAmount { - additional_amount: String, + additional_amount: StringMajorUnit, currency: String, } @@ -1102,7 +1096,7 @@ impl // } fn build_bill_to( - address_details: Option<&payments::Address>, + address_details: Option<&hyperswitch_domain_models::address::Address>, email: pii::Email, ) -> Result> { let default_address = BillTo { diff --git a/crates/router/src/connector/datatrans.rs b/crates/router/src/connector/datatrans.rs index 9c7772c5b3ef..e6f0ebd09850 100644 --- a/crates/router/src/connector/datatrans.rs +++ b/crates/router/src/connector/datatrans.rs @@ -4,8 +4,8 @@ use base64::Engine; use common_utils::types::{AmountConvertor, MinorUnit, MinorUnitForConnector}; use error_stack::{report, ResultExt}; use masking::PeekInterface; -use transformers::{self as datatrans}; +use self::transformers as datatrans; use super::{utils as connector_utils, utils::RefundsRequestData}; use crate::{ configs::settings, diff --git a/crates/router/src/connector/globalpay/requests.rs b/crates/router/src/connector/globalpay/requests.rs index 9ccfcd90be38..223be54d3fd5 100644 --- a/crates/router/src/connector/globalpay/requests.rs +++ b/crates/router/src/connector/globalpay/requests.rs @@ -99,7 +99,6 @@ pub struct GlobalpayRefreshTokenRequest { } #[derive(Debug, Serialize, Deserialize)] - pub struct CurrencyConversion { /// A unique identifier generated by Global Payments to identify the currency conversion. It /// can be used to reference a currency conversion when processing a sale or a refund @@ -108,7 +107,6 @@ pub struct CurrencyConversion { } #[derive(Debug, Serialize, Deserialize)] - pub struct Device { pub capabilities: Option, @@ -128,7 +126,6 @@ pub struct Device { } #[derive(Debug, Serialize, Deserialize)] - pub struct Capabilities { pub authorization_modes: Option>, /// The number of lines that can be used to display information on the device. @@ -146,7 +143,6 @@ pub struct Capabilities { } #[derive(Debug, Serialize, Deserialize)] - pub struct Lodging { /// A reference that identifies the booking reference for a lodging stay. pub booking_reference: Option, @@ -163,7 +159,6 @@ pub struct Lodging { } #[derive(Debug, Serialize, Deserialize)] - pub struct LodgingChargeItem { pub payment_method_program_codes: Option>, /// A reference that identifies the charge item, such as a lodging folio number. @@ -195,7 +190,6 @@ pub struct Notifications { } #[derive(Debug, Serialize, Deserialize)] - pub struct Order { /// Merchant defined field common to all transactions that are part of the same order. pub reference: Option, @@ -239,7 +233,6 @@ pub struct PaymentMethod { } #[derive(Debug, Serialize, Deserialize)] - pub struct Apm { /// A string used to identify the payment method provider being used to execute this /// transaction. @@ -247,9 +240,7 @@ pub struct Apm { } /// Information outlining the degree of authentication executed related to a transaction. - #[derive(Debug, Serialize, Deserialize)] - pub struct Authentication { /// Information outlining the degree of 3D Secure authentication executed. pub three_ds: Option, @@ -259,9 +250,7 @@ pub struct Authentication { } /// Information outlining the degree of 3D Secure authentication executed. - #[derive(Debug, Serialize, Deserialize)] - pub struct ThreeDs { /// The reference created by the 3DSecure Directory Server to identify the specific /// authentication attempt. @@ -284,7 +273,6 @@ pub struct ThreeDs { } #[derive(Debug, Serialize, Deserialize)] - pub struct BankTransfer { /// The number or reference for the payer's bank account. pub account_number: Option>, @@ -298,7 +286,6 @@ pub struct BankTransfer { pub sec_code: Option, } #[derive(Debug, Serialize, Deserialize)] - pub struct Bank { pub address: Option
, /// The local identifier code for the bank. @@ -401,7 +388,6 @@ pub enum AuthorizationMode { /// requested amount. /// pub example: PARTIAL /// - /// /// Describes whether the device can process partial authorizations. Partial, } @@ -428,7 +414,6 @@ pub enum CaptureMode { /// Describes whether the transaction was processed in a face to face(CP) scenario or a /// Customer Not Present (CNP) scenario. - #[derive(Debug, Default, Serialize, Deserialize)] pub enum Channel { #[default] @@ -609,7 +594,6 @@ pub enum NumberType { } /// Indicates how the transaction was authorized by the merchant. - #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum SecCode { @@ -766,7 +750,6 @@ pub enum CardStorageMode { /// Indicates the transaction processing model being executed when using stored /// credentials. - #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum Model { diff --git a/crates/router/src/connector/klarna/transformers.rs b/crates/router/src/connector/klarna/transformers.rs index 62a5cef0bcae..803dc4a428d2 100644 --- a/crates/router/src/connector/klarna/transformers.rs +++ b/crates/router/src/connector/klarna/transformers.rs @@ -218,7 +218,7 @@ impl TryFrom<&KlarnaRouterData<&types::PaymentsAuthorizeRouterData>> for KlarnaP } fn get_address_info( - address: Option<&payments::Address>, + address: Option<&hyperswitch_domain_models::address::Address>, ) -> Option>> { address.and_then(|add| { add.address.as_ref().map( diff --git a/crates/router/src/connector/netcetera/netcetera_types.rs b/crates/router/src/connector/netcetera/netcetera_types.rs index 68a01b26fba8..ac6aad8c1366 100644 --- a/crates/router/src/connector/netcetera/netcetera_types.rs +++ b/crates/router/src/connector/netcetera/netcetera_types.rs @@ -208,7 +208,7 @@ pub struct ThreeDSRequestorAuthenticationInformation { /// card to a wallet. /// /// This field is optional. The accepted values are: -/// +/// /// - 01 -> No preference /// - 02 -> No challenge requested /// - 03 -> Challenge requested: 3DS Requestor Preference @@ -686,15 +686,15 @@ pub struct Cardholder { impl TryFrom<( - api_models::payments::Address, - Option, + hyperswitch_domain_models::address::Address, + Option, )> for Cardholder { type Error = error_stack::Report; fn try_from( (billing_address, shipping_address): ( - api_models::payments::Address, - Option, + hyperswitch_domain_models::address::Address, + Option, ), ) -> Result { Ok(Self { @@ -801,9 +801,11 @@ pub struct PhoneNumber { subscriber: Option>, } -impl TryFrom for PhoneNumber { +impl TryFrom for PhoneNumber { type Error = error_stack::Report; - fn try_from(value: api_models::payments::PhoneDetails) -> Result { + fn try_from( + value: hyperswitch_domain_models::address::PhoneDetails, + ) -> Result { Ok(Self { country_code: Some(value.extract_country_code()?), subscriber: value.number, diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index 7f2d0d0e608e..11e01b78e134 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -653,7 +653,9 @@ impl TryFrom<&types::SetupMandateRouterData> for PaypalZeroMandateRequest { } } -fn get_address_info(payment_address: Option<&api_models::payments::Address>) -> Option
{ +fn get_address_info( + payment_address: Option<&hyperswitch_domain_models::address::Address>, +) -> Option
{ let address = payment_address.and_then(|payment_address| payment_address.address.as_ref()); match address { Some(address) => address.get_optional_country().map(|country| Address { @@ -2970,7 +2972,6 @@ pub struct PaypalSourceVerificationRequest { } #[derive(Deserialize, Serialize, Debug)] - pub struct PaypalSourceVerificationResponse { pub verification_status: PaypalSourceVerificationStatus, } diff --git a/crates/router/src/connector/riskified/transformers/api.rs b/crates/router/src/connector/riskified/transformers/api.rs index c2da0193f996..e8c1b8744179 100644 --- a/crates/router/src/connector/riskified/transformers/api.rs +++ b/crates/router/src/connector/riskified/transformers/api.rs @@ -620,9 +620,11 @@ pub struct ErrorData { pub message: String, } -impl TryFrom<&api_models::payments::Address> for OrderAddress { +impl TryFrom<&hyperswitch_domain_models::address::Address> for OrderAddress { type Error = Error; - fn try_from(address_info: &api_models::payments::Address) -> Result { + fn try_from( + address_info: &hyperswitch_domain_models::address::Address, + ) -> Result { let address = address_info .clone() @@ -657,7 +659,6 @@ fn get_fulfillment_status( } #[derive(Debug, Clone, Deserialize, Serialize)] - pub struct RiskifiedWebhookBody { pub id: String, pub status: RiskifiedWebhookStatus, diff --git a/crates/router/src/connector/signifyd/transformers/api.rs b/crates/router/src/connector/signifyd/transformers/api.rs index 348ca3d099a6..028c0e825189 100644 --- a/crates/router/src/connector/signifyd/transformers/api.rs +++ b/crates/router/src/connector/signifyd/transformers/api.rs @@ -702,7 +702,6 @@ impl TryFrom<&frm_types::FrmRecordReturnRouterData> for SignifydPaymentsRecordRe #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] - pub struct SignifydWebhookBody { pub order_id: String, pub review_disposition: ReviewDisposition, diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index ed4b97e2a996..c3d6806ff0ea 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -54,7 +54,7 @@ use crate::{ pub fn missing_field_err( message: &'static str, -) -> Box error_stack::Report + '_> { +) -> Box error_stack::Report + 'static> { Box::new(move || { errors::ConnectorError::MissingRequiredField { field_name: message, @@ -79,14 +79,21 @@ impl AccessTokenRequestInfo for types::RefreshTokenRouterData { } pub trait RouterData { - fn get_billing(&self) -> Result<&api::Address, Error>; + fn get_billing(&self) -> Result<&hyperswitch_domain_models::address::Address, Error>; fn get_billing_country(&self) -> Result; - fn get_billing_phone(&self) -> Result<&api::PhoneDetails, Error>; + fn get_billing_phone(&self) + -> Result<&hyperswitch_domain_models::address::PhoneDetails, Error>; fn get_description(&self) -> Result; fn get_return_url(&self) -> Result; - fn get_billing_address(&self) -> Result<&api::AddressDetails, Error>; - fn get_shipping_address(&self) -> Result<&api::AddressDetails, Error>; - fn get_shipping_address_with_phone_number(&self) -> Result<&api::Address, Error>; + fn get_billing_address( + &self, + ) -> Result<&hyperswitch_domain_models::address::AddressDetails, Error>; + fn get_shipping_address( + &self, + ) -> Result<&hyperswitch_domain_models::address::AddressDetails, Error>; + fn get_shipping_address_with_phone_number( + &self, + ) -> Result<&hyperswitch_domain_models::address::Address, Error>; fn get_connector_meta(&self) -> Result; fn get_session_token(&self) -> Result; fn get_billing_first_name(&self) -> Result, Error>; @@ -112,8 +119,8 @@ pub trait RouterData { #[cfg(feature = "payouts")] fn get_quote_id(&self) -> Result; - fn get_optional_billing(&self) -> Option<&api::Address>; - fn get_optional_shipping(&self) -> Option<&api::Address>; + fn get_optional_billing(&self) -> Option<&hyperswitch_domain_models::address::Address>; + fn get_optional_shipping(&self) -> Option<&hyperswitch_domain_models::address::Address>; fn get_optional_shipping_line1(&self) -> Option>; fn get_optional_shipping_line2(&self) -> Option>; fn get_optional_shipping_city(&self) -> Option; @@ -191,7 +198,7 @@ pub fn get_unimplemented_payment_method_error_message(connector: &str) -> String } impl RouterData for types::RouterData { - fn get_billing(&self) -> Result<&api::Address, Error> { + fn get_billing(&self) -> Result<&hyperswitch_domain_models::address::Address, Error> { self.address .get_payment_method_billing() .ok_or_else(missing_field_err("billing")) @@ -207,18 +214,20 @@ impl RouterData for types::RouterData Result<&api::PhoneDetails, Error> { + fn get_billing_phone( + &self, + ) -> Result<&hyperswitch_domain_models::address::PhoneDetails, Error> { self.address .get_payment_method_billing() .and_then(|a| a.phone.as_ref()) .ok_or_else(missing_field_err("billing.phone")) } - fn get_optional_billing(&self) -> Option<&api::Address> { + fn get_optional_billing(&self) -> Option<&hyperswitch_domain_models::address::Address> { self.address.get_payment_method_billing() } - fn get_optional_shipping(&self) -> Option<&api::Address> { + fn get_optional_shipping(&self) -> Option<&hyperswitch_domain_models::address::Address> { self.address.get_shipping() } @@ -317,7 +326,9 @@ impl RouterData for types::RouterData Result<&api::AddressDetails, Error> { + fn get_billing_address( + &self, + ) -> Result<&hyperswitch_domain_models::address::AddressDetails, Error> { self.address .get_payment_method_billing() .as_ref() @@ -534,14 +545,18 @@ impl RouterData for types::RouterData Result<&api::AddressDetails, Error> { + fn get_shipping_address( + &self, + ) -> Result<&hyperswitch_domain_models::address::AddressDetails, Error> { self.address .get_shipping() .and_then(|a| a.address.as_ref()) .ok_or_else(missing_field_err("shipping.address")) } - fn get_shipping_address_with_phone_number(&self) -> Result<&api::Address, Error> { + fn get_shipping_address_with_phone_number( + &self, + ) -> Result<&hyperswitch_domain_models::address::Address, Error> { self.address .get_shipping() .ok_or_else(missing_field_err("shipping")) @@ -602,7 +617,7 @@ pub trait AddressData { fn get_optional_full_name(&self) -> Option>; } -impl AddressData for api::Address { +impl AddressData for hyperswitch_domain_models::address::Address { fn get_email(&self) -> Result { self.email.clone().ok_or_else(missing_field_err("email")) } @@ -1762,7 +1777,7 @@ pub trait PhoneDetailsData { fn extract_country_code(&self) -> Result; } -impl PhoneDetailsData for api::PhoneDetails { +impl PhoneDetailsData for hyperswitch_domain_models::address::PhoneDetails { fn get_country_code(&self) -> Result { self.country_code .clone() @@ -1811,7 +1826,7 @@ pub trait AddressDetailsData { fn get_optional_country(&self) -> Option; } -impl AddressDetailsData for api::AddressDetails { +impl AddressDetailsData for hyperswitch_domain_models::address::AddressDetails { fn get_first_name(&self) -> Result<&Secret, Error> { self.first_name .as_ref() diff --git a/crates/router/src/connector/wellsfargo/transformers.rs b/crates/router/src/connector/wellsfargo/transformers.rs index 3a2e35190e60..42ee4acadef1 100644 --- a/crates/router/src/connector/wellsfargo/transformers.rs +++ b/crates/router/src/connector/wellsfargo/transformers.rs @@ -802,7 +802,9 @@ impl } } -fn get_phone_number(item: Option<&payments::Address>) -> Option> { +fn get_phone_number( + item: Option<&hyperswitch_domain_models::address::Address>, +) -> Option> { item.as_ref() .and_then(|billing| billing.phone.as_ref()) .and_then(|phone| { @@ -816,7 +818,7 @@ fn get_phone_number(item: Option<&payments::Address>) -> Option> } fn build_bill_to( - address_details: Option<&payments::Address>, + address_details: Option<&hyperswitch_domain_models::address::Address>, email: pii::Email, ) -> Result> { let phone_number = get_phone_number(address_details); diff --git a/crates/router/src/connector/wellsfargopayout.rs b/crates/router/src/connector/wellsfargopayout.rs index 51b303494bbb..fe8f5dda25fe 100644 --- a/crates/router/src/connector/wellsfargopayout.rs +++ b/crates/router/src/connector/wellsfargopayout.rs @@ -3,9 +3,9 @@ pub mod transformers; use common_utils::types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector}; use error_stack::{report, ResultExt}; use masking::ExposeInterface; -use transformers as wellsfargopayout; -use super::utils::{self as connector_utils}; +use self::transformers as wellsfargopayout; +use super::utils as connector_utils; use crate::{ configs::settings, core::errors::{self, CustomResult}, diff --git a/crates/router/src/connector/wise/transformers.rs b/crates/router/src/connector/wise/transformers.rs index 94849f2b1ca7..513a762bfd3c 100644 --- a/crates/router/src/connector/wise/transformers.rs +++ b/crates/router/src/connector/wise/transformers.rs @@ -306,7 +306,7 @@ pub enum WiseStatus { #[cfg(feature = "payouts")] fn get_payout_address_details( - address: Option<&api_models::payments::Address>, + address: Option<&hyperswitch_domain_models::address::Address>, ) -> Option { address.and_then(|add| { add.address.as_ref().map(|a| WiseAddressDetails { @@ -323,7 +323,7 @@ fn get_payout_address_details( #[cfg(feature = "payouts")] fn get_payout_bank_details( payout_method_data: PayoutMethodData, - address: Option<&api_models::payments::Address>, + address: Option<&hyperswitch_domain_models::address::Address>, entity_type: PayoutEntityType, ) -> Result { let wise_address_details = match get_payout_address_details(address) { diff --git a/crates/router/src/consts.rs b/crates/router/src/consts.rs index 9b02c67ce6a7..2c02b8b14836 100644 --- a/crates/router/src/consts.rs +++ b/crates/router/src/consts.rs @@ -52,9 +52,6 @@ pub(crate) const DEFAULT_NOTIFICATION_SCRIPT_LANGUAGE: &str = "en-US"; pub(crate) const BASE64_ENGINE: base64::engine::GeneralPurpose = consts::BASE64_ENGINE; -pub(crate) const BASE64_ENGINE_URL_SAFE: base64::engine::GeneralPurpose = - base64::engine::general_purpose::URL_SAFE; - pub(crate) const API_KEY_LENGTH: usize = 64; // Apple Pay validation url diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 6d4dde53082c..055c428b1fbc 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1199,7 +1199,7 @@ struct ConnectorAuthTypeAndMetadataValidation<'a> { connector_meta_data: &'a Option, } -impl<'a> ConnectorAuthTypeAndMetadataValidation<'a> { +impl ConnectorAuthTypeAndMetadataValidation<'_> { pub fn validate_auth_and_metadata_type( &self, ) -> Result<(), error_stack::Report> { @@ -1576,7 +1576,7 @@ struct ConnectorAuthTypeValidation<'a> { auth_type: &'a types::ConnectorAuthType, } -impl<'a> ConnectorAuthTypeValidation<'a> { +impl ConnectorAuthTypeValidation<'_> { fn validate_connector_auth_type( &self, ) -> Result<(), error_stack::Report> { @@ -1666,7 +1666,7 @@ struct ConnectorStatusAndDisabledValidation<'a> { current_status: &'a api_enums::ConnectorStatus, } -impl<'a> ConnectorStatusAndDisabledValidation<'a> { +impl ConnectorStatusAndDisabledValidation<'_> { fn validate_status_and_disabled( &self, ) -> RouterResult<(api_enums::ConnectorStatus, Option)> { @@ -1709,7 +1709,7 @@ struct PaymentMethodsEnabled<'a> { payment_methods_enabled: &'a Option>, } -impl<'a> PaymentMethodsEnabled<'a> { +impl PaymentMethodsEnabled<'_> { fn get_payment_methods_enabled(&self) -> RouterResult>> { let mut vec = Vec::new(); let payment_methods_enabled = match self.payment_methods_enabled.clone() { @@ -1735,7 +1735,7 @@ struct ConnectorMetadata<'a> { connector_metadata: &'a Option, } -impl<'a> ConnectorMetadata<'a> { +impl ConnectorMetadata<'_> { fn validate_apple_pay_certificates_in_mca_metadata(&self) -> RouterResult<()> { self.connector_metadata .clone() @@ -1826,7 +1826,7 @@ struct ConnectorTypeAndConnectorName<'a> { connector_name: &'a api_enums::Connector, } -impl<'a> ConnectorTypeAndConnectorName<'a> { +impl ConnectorTypeAndConnectorName<'_> { fn get_routable_connector(&self) -> RouterResult> { let mut routable_connector = api_enums::RoutableConnectors::from_str(&self.connector_name.to_string()).ok(); diff --git a/crates/router/src/core/authentication.rs b/crates/router/src/core/authentication.rs index b4718a64de5a..09cebda49088 100644 --- a/crates/router/src/core/authentication.rs +++ b/crates/router/src/core/authentication.rs @@ -24,8 +24,8 @@ pub async fn perform_authentication( authentication_connector: String, payment_method_data: domain::PaymentMethodData, payment_method: common_enums::PaymentMethod, - billing_address: payments::Address, - shipping_address: Option, + billing_address: hyperswitch_domain_models::address::Address, + shipping_address: Option, browser_details: Option, merchant_connector_account: payments_core::helpers::MerchantConnectorAccountType, amount: Option, diff --git a/crates/router/src/core/authentication/transformers.rs b/crates/router/src/core/authentication/transformers.rs index bcbd1481711d..c4b35d527980 100644 --- a/crates/router/src/core/authentication/transformers.rs +++ b/crates/router/src/core/authentication/transformers.rs @@ -28,8 +28,8 @@ pub fn construct_authentication_router_data( authentication_connector: String, payment_method_data: domain::PaymentMethodData, payment_method: PaymentMethod, - billing_address: payments::Address, - shipping_address: Option, + billing_address: hyperswitch_domain_models::address::Address, + shipping_address: Option, browser_details: Option, amount: Option, currency: Option, diff --git a/crates/router/src/core/errors/user.rs b/crates/router/src/core/errors/user.rs index 5c7b77246e27..33477df6330a 100644 --- a/crates/router/src/core/errors/user.rs +++ b/crates/router/src/core/errors/user.rs @@ -96,6 +96,16 @@ pub enum UserErrors { MaxRecoveryCodeAttemptsReached, #[error("Forbidden tenant id")] ForbiddenTenantId, + #[error("Error Uploading file to Theme Storage")] + ErrorUploadingFile, + #[error("Error Retrieving file from Theme Storage")] + ErrorRetrievingFile, + #[error("Theme not found")] + ThemeNotFound, + #[error("Theme with lineage already exists")] + ThemeAlreadyExists, + #[error("Invalid field: {0} in lineage")] + InvalidThemeLineage(String), } impl common_utils::errors::ErrorSwitch for UserErrors { @@ -244,57 +254,93 @@ impl common_utils::errors::ErrorSwitch { AER::BadRequest(ApiError::new(sub_code, 50, self.get_error_message(), None)) } + Self::ErrorUploadingFile => AER::InternalServerError(ApiError::new( + sub_code, + 51, + self.get_error_message(), + None, + )), + Self::ErrorRetrievingFile => AER::InternalServerError(ApiError::new( + sub_code, + 52, + self.get_error_message(), + None, + )), + Self::ThemeNotFound => { + AER::NotFound(ApiError::new(sub_code, 53, self.get_error_message(), None)) + } + Self::ThemeAlreadyExists => { + AER::BadRequest(ApiError::new(sub_code, 54, self.get_error_message(), None)) + } + Self::InvalidThemeLineage(_) => { + AER::BadRequest(ApiError::new(sub_code, 55, self.get_error_message(), None)) + } } } } impl UserErrors { - pub fn get_error_message(&self) -> &str { + pub fn get_error_message(&self) -> String { match self { - Self::InternalServerError => "Something went wrong", - Self::InvalidCredentials => "Incorrect email or password", - Self::UserNotFound => "Email doesn’t exist. Register", - Self::UserExists => "An account already exists with this email", - Self::LinkInvalid => "Invalid or expired link", - Self::UnverifiedUser => "Kindly verify your account", - Self::InvalidOldPassword => "Old password incorrect. Please enter the correct password", - Self::EmailParsingError => "Invalid Email", - Self::NameParsingError => "Invalid Name", - Self::PasswordParsingError => "Invalid Password", - Self::UserAlreadyVerified => "User already verified", - Self::CompanyNameParsingError => "Invalid Company Name", - Self::MerchantAccountCreationError(error_message) => error_message, - Self::InvalidEmailError => "Invalid Email", - Self::MerchantIdNotFound => "Invalid Merchant ID", - Self::MetadataAlreadySet => "Metadata already set", - Self::DuplicateOrganizationId => "An Organization with the id already exists", - Self::InvalidRoleId => "Invalid Role ID", - Self::InvalidRoleOperation => "User Role Operation Not Supported", - Self::IpAddressParsingFailed => "Something went wrong", - Self::InvalidMetadataRequest => "Invalid Metadata Request", - Self::MerchantIdParsingError => "Invalid Merchant Id", - Self::ChangePasswordError => "Old and new password cannot be same", - Self::InvalidDeleteOperation => "Delete Operation Not Supported", - Self::MaxInvitationsError => "Maximum invite count per request exceeded", - Self::RoleNotFound => "Role Not Found", - Self::InvalidRoleOperationWithMessage(error_message) => error_message, - Self::RoleNameParsingError => "Invalid Role Name", - Self::RoleNameAlreadyExists => "Role name already exists", - Self::TotpNotSetup => "TOTP not setup", - Self::InvalidTotp => "Invalid TOTP", - Self::TotpRequired => "TOTP required", - Self::InvalidRecoveryCode => "Invalid Recovery Code", - Self::MaxTotpAttemptsReached => "Maximum attempts reached for TOTP", - Self::MaxRecoveryCodeAttemptsReached => "Maximum attempts reached for Recovery Code", - Self::TwoFactorAuthRequired => "Two factor auth required", - Self::TwoFactorAuthNotSetup => "Two factor auth not setup", - Self::TotpSecretNotFound => "TOTP secret not found", - Self::UserAuthMethodAlreadyExists => "User auth method already exists", - Self::InvalidUserAuthMethodOperation => "Invalid user auth method operation", - Self::AuthConfigParsingError => "Auth config parsing error", - Self::SSOFailed => "Invalid SSO request", - Self::JwtProfileIdMissing => "profile_id missing in JWT", - Self::ForbiddenTenantId => "Forbidden tenant id", + Self::InternalServerError => "Something went wrong".to_string(), + Self::InvalidCredentials => "Incorrect email or password".to_string(), + Self::UserNotFound => "Email doesn’t exist. Register".to_string(), + Self::UserExists => "An account already exists with this email".to_string(), + Self::LinkInvalid => "Invalid or expired link".to_string(), + Self::UnverifiedUser => "Kindly verify your account".to_string(), + Self::InvalidOldPassword => { + "Old password incorrect. Please enter the correct password".to_string() + } + Self::EmailParsingError => "Invalid Email".to_string(), + Self::NameParsingError => "Invalid Name".to_string(), + Self::PasswordParsingError => "Invalid Password".to_string(), + Self::UserAlreadyVerified => "User already verified".to_string(), + Self::CompanyNameParsingError => "Invalid Company Name".to_string(), + Self::MerchantAccountCreationError(error_message) => error_message.to_string(), + Self::InvalidEmailError => "Invalid Email".to_string(), + Self::MerchantIdNotFound => "Invalid Merchant ID".to_string(), + Self::MetadataAlreadySet => "Metadata already set".to_string(), + Self::DuplicateOrganizationId => { + "An Organization with the id already exists".to_string() + } + Self::InvalidRoleId => "Invalid Role ID".to_string(), + Self::InvalidRoleOperation => "User Role Operation Not Supported".to_string(), + Self::IpAddressParsingFailed => "Something went wrong".to_string(), + Self::InvalidMetadataRequest => "Invalid Metadata Request".to_string(), + Self::MerchantIdParsingError => "Invalid Merchant Id".to_string(), + Self::ChangePasswordError => "Old and new password cannot be same".to_string(), + Self::InvalidDeleteOperation => "Delete Operation Not Supported".to_string(), + Self::MaxInvitationsError => "Maximum invite count per request exceeded".to_string(), + Self::RoleNotFound => "Role Not Found".to_string(), + Self::InvalidRoleOperationWithMessage(error_message) => error_message.to_string(), + Self::RoleNameParsingError => "Invalid Role Name".to_string(), + Self::RoleNameAlreadyExists => "Role name already exists".to_string(), + Self::TotpNotSetup => "TOTP not setup".to_string(), + Self::InvalidTotp => "Invalid TOTP".to_string(), + Self::TotpRequired => "TOTP required".to_string(), + Self::InvalidRecoveryCode => "Invalid Recovery Code".to_string(), + Self::MaxTotpAttemptsReached => "Maximum attempts reached for TOTP".to_string(), + Self::MaxRecoveryCodeAttemptsReached => { + "Maximum attempts reached for Recovery Code".to_string() + } + Self::TwoFactorAuthRequired => "Two factor auth required".to_string(), + Self::TwoFactorAuthNotSetup => "Two factor auth not setup".to_string(), + Self::TotpSecretNotFound => "TOTP secret not found".to_string(), + Self::UserAuthMethodAlreadyExists => "User auth method already exists".to_string(), + Self::InvalidUserAuthMethodOperation => { + "Invalid user auth method operation".to_string() + } + Self::AuthConfigParsingError => "Auth config parsing error".to_string(), + Self::SSOFailed => "Invalid SSO request".to_string(), + Self::JwtProfileIdMissing => "profile_id missing in JWT".to_string(), + Self::ForbiddenTenantId => "Forbidden tenant id".to_string(), + Self::ErrorUploadingFile => "Error Uploading file to Theme Storage".to_string(), + Self::ErrorRetrievingFile => "Error Retrieving file from Theme Storage".to_string(), + Self::ThemeNotFound => "Theme not found".to_string(), + Self::ThemeAlreadyExists => "Theme with lineage already exists".to_string(), + Self::InvalidThemeLineage(field_name) => { + format!("Invalid field: {} in lineage", field_name) + } } } } diff --git a/crates/router/src/core/gsm.rs b/crates/router/src/core/gsm.rs index 4a678a5c4089..c7daee111a9a 100644 --- a/crates/router/src/core/gsm.rs +++ b/crates/router/src/core/gsm.rs @@ -67,6 +67,7 @@ pub async fn update_gsm_rule( step_up_possible, unified_code, unified_message, + error_category, } = gsm_request; GsmInterface::update_gsm_rule( db, @@ -82,6 +83,7 @@ pub async fn update_gsm_rule( step_up_possible, unified_code, unified_message, + error_category, }, ) .await diff --git a/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js b/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js index b79e2284a567..ab46223df177 100644 --- a/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js +++ b/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js @@ -39,7 +39,7 @@ function initializeSDK() { paymentDetails.sdk_layout === "accordion" ? "accordion" : paymentDetails.sdk_layout; - + var hideCardNicknameField = paymentDetails.hide_card_nickname_field; var unifiedCheckoutOptions = { displaySavedPaymentMethodsCheckbox: false, displaySavedPaymentMethods: false, @@ -57,7 +57,7 @@ function initializeSDK() { }, }, showCardFormByDefault: paymentDetails.show_card_form_by_default, - hideCardNicknameField: false, + hideCardNicknameField: hideCardNicknameField, }; // @ts-ignore unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions); @@ -83,5 +83,10 @@ function redirectToStatus() { arr.splice(0, 2); arr.unshift("status"); arr.unshift("payment_link"); - window.location.href = window.location.origin + "/" + arr.join("/") + "?locale=" + paymentDetails.locale; + window.location.href = + window.location.origin + + "/" + + arr.join("/") + + "?locale=" + + paymentDetails.locale; } diff --git a/crates/router/src/core/payment_methods.rs b/crates/router/src/core/payment_methods.rs index 599d696ec06d..a7c4a4c4ade3 100644 --- a/crates/router/src/core/payment_methods.rs +++ b/crates/router/src/core/payment_methods.rs @@ -754,7 +754,7 @@ pub(crate) async fn get_payment_method_create_request( payment_method_type: Option, customer_id: &Option, billing_name: Option>, - payment_method_billing_address: Option<&api_models::payments::Address>, + payment_method_billing_address: Option<&hyperswitch_domain_models::address::Address>, ) -> RouterResult { match payment_method_data { Some(pm_data) => match payment_method { @@ -789,7 +789,8 @@ pub(crate) async fn get_payment_method_create_request( .map(|card_network| card_network.to_string()), client_secret: None, payment_method_data: None, - billing: payment_method_billing_address.cloned(), + //TODO: why are we using api model in router internally + billing: payment_method_billing_address.cloned().map(From::from), connector_mandate_details: None, network_transaction_id: None, }; diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 9cfe6e6ec738..ad612ed6f3be 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -3149,7 +3149,7 @@ pub fn get_banks( .iter() .skip(1) .fold(first_element.to_owned(), |acc, hs| { - acc.intersection(hs).cloned().collect() + acc.intersection(hs).copied().collect() }); } @@ -3617,7 +3617,7 @@ pub async fn list_payment_methods( .transpose() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Invalid PaymentRoutingInfo format found in payment attempt")? - .unwrap_or_else(|| storage::PaymentRoutingInfo { + .unwrap_or(storage::PaymentRoutingInfo { algorithm: None, pre_routing_results: None, }); diff --git a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs index ff52799ed631..6a2b3198e932 100644 --- a/crates/router/src/core/payment_methods/surcharge_decision_configs.rs +++ b/crates/router/src/core/payment_methods/surcharge_decision_configs.rs @@ -122,7 +122,7 @@ pub async fn perform_surcharge_decision_management_for_payment_method_list( algorithm_ref: routing::RoutingAlgorithmRef, payment_attempt: &storage::PaymentAttempt, payment_intent: &storage::PaymentIntent, - billing_address: Option, + billing_address: Option, response_payment_method_types: &mut [api_models::payment_methods::ResponsePaymentMethodsEnabled], ) -> ConditionalConfigResult<( types::SurchargeMetadata, @@ -242,7 +242,7 @@ pub async fn perform_surcharge_decision_management_for_session_flow( algorithm_ref: routing::RoutingAlgorithmRef, payment_attempt: &storage::PaymentAttempt, payment_intent: &storage::PaymentIntent, - billing_address: Option, + billing_address: Option, payment_method_type_list: &Vec, ) -> ConditionalConfigResult { let mut surcharge_metadata = types::SurchargeMetadata::new(payment_attempt.attempt_id.clone()); diff --git a/crates/router/src/core/payment_methods/utils.rs b/crates/router/src/core/payment_methods/utils.rs index 1afdaaab0622..604e8c706262 100644 --- a/crates/router/src/core/payment_methods/utils.rs +++ b/crates/router/src/core/payment_methods/utils.rs @@ -737,7 +737,7 @@ fn compile_accepted_currency_for_mca( let config_currency: Vec = Vec::from_iter(config_currencies) .into_iter() - .cloned() + .copied() .collect(); let dir_currencies: Vec = config_currency @@ -767,7 +767,7 @@ fn compile_accepted_currency_for_mca( let config_currency: Vec = Vec::from_iter(config_currencies) .into_iter() - .cloned() + .copied() .collect(); let dir_currencies: Vec = config_currency diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index fd61fcacf5af..fd9eaaa9c77d 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -1223,7 +1223,7 @@ pub async fn call_surcharge_decision_management_for_session_flow( _business_profile: &domain::Profile, _payment_attempt: &storage::PaymentAttempt, _payment_intent: &storage::PaymentIntent, - _billing_address: Option, + _billing_address: Option, _session_connector_data: &[api::SessionConnectorData], ) -> RouterResult> { todo!() @@ -1237,7 +1237,7 @@ pub async fn call_surcharge_decision_management_for_session_flow( _business_profile: &domain::Profile, payment_attempt: &storage::PaymentAttempt, payment_intent: &storage::PaymentIntent, - billing_address: Option, + billing_address: Option, session_connector_data: &[api::SessionConnectorData], ) -> RouterResult> { if let Some(surcharge_amount) = payment_attempt.net_amount.get_surcharge_amount() { @@ -1484,7 +1484,7 @@ where F: Send + Clone + Sync, Req: Send + Sync, FData: Send + Sync + Clone, - Op: Operation + Send + Sync + Clone, + Op: Operation + ValidateStatusForOperation + Send + Sync + Clone, Req: Debug, D: OperationSessionGetters + OperationSessionSetters + Send + Sync + Clone, Res: transformers::ToResponse, @@ -4253,7 +4253,7 @@ where #[derive(Clone, serde::Serialize, Debug)] pub struct TaxData { - pub shipping_details: api_models::payments::Address, + pub shipping_details: hyperswitch_domain_models::address::Address, pub payment_method_type: enums::PaymentMethodType, } @@ -4312,7 +4312,7 @@ pub fn if_not_create_change_operation<'a, Op, F>( status: storage_enums::IntentStatus, confirm: Option, current: &'a Op, -) -> BoxedOperation<'_, F, api::PaymentsRequest, PaymentData> +) -> BoxedOperation<'a, F, api::PaymentsRequest, PaymentData> where F: Send + Clone, Op: Operation> + Send + Sync, @@ -4336,7 +4336,7 @@ where pub fn is_confirm<'a, F: Clone + Send, R, Op>( operation: &'a Op, confirm: Option, -) -> BoxedOperation<'_, F, R, PaymentData> +) -> BoxedOperation<'a, F, R, PaymentData> where PaymentConfirm: Operation>, &'a PaymentConfirm: Operation>, @@ -5044,7 +5044,7 @@ where .transpose() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Invalid straight through algorithm format found in payment attempt")? - .unwrap_or_else(|| storage::PaymentRoutingInfo { + .unwrap_or(storage::PaymentRoutingInfo { algorithm: None, pre_routing_results: None, }), @@ -6686,7 +6686,7 @@ pub trait OperationSessionGetters { fn get_currency(&self) -> storage_enums::Currency; fn get_amount(&self) -> api::Amount; fn get_payment_attempt_connector(&self) -> Option<&str>; - fn get_billing_address(&self) -> Option; + fn get_billing_address(&self) -> Option; fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData>; fn get_sessions_token(&self) -> Vec; fn get_token_data(&self) -> Option<&storage::PaymentTokenData>; @@ -6740,6 +6740,7 @@ pub trait OperationSessionSetters { fn set_connector_in_payment_attempt(&mut self, connector: Option); } +#[cfg(feature = "v1")] impl OperationSessionGetters for PaymentData { fn get_payment_attempt(&self) -> &storage::PaymentAttempt { &self.payment_attempt @@ -6840,7 +6841,7 @@ impl OperationSessionGetters for PaymentData { self.payment_attempt.connector.as_deref() } - fn get_billing_address(&self) -> Option { + fn get_billing_address(&self) -> Option { self.address.get_payment_method_billing().cloned() } @@ -6869,15 +6870,15 @@ impl OperationSessionGetters for PaymentData { self.payment_attempt.capture_method } - #[cfg(feature = "v2")] - fn get_capture_method(&self) -> Option { - Some(self.payment_intent.capture_method) - } + // #[cfg(feature = "v2")] + // fn get_capture_method(&self) -> Option { + // Some(self.payment_intent.capture_method) + // } - #[cfg(feature = "v2")] - fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { - todo!(); - } + // #[cfg(feature = "v2")] + // fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { + // todo!(); + // } } #[cfg(feature = "v1")] @@ -7082,7 +7083,7 @@ impl OperationSessionGetters for PaymentIntentData { todo!() } - fn get_billing_address(&self) -> Option { + fn get_billing_address(&self) -> Option { todo!() } @@ -7110,7 +7111,6 @@ impl OperationSessionGetters for PaymentIntentData { todo!() } - #[cfg(feature = "v2")] fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { todo!(); } @@ -7219,9 +7219,8 @@ impl OperationSessionGetters for PaymentConfirmData { todo!() } - // what is this address find out and not required remove this fn get_address(&self) -> &PaymentAddress { - todo!() + &self.payment_address } fn get_creds_identifier(&self) -> Option<&str> { @@ -7296,7 +7295,7 @@ impl OperationSessionGetters for PaymentConfirmData { todo!() } - fn get_billing_address(&self) -> Option { + fn get_billing_address(&self) -> Option { todo!() } @@ -7324,9 +7323,8 @@ impl OperationSessionGetters for PaymentConfirmData { todo!() } - #[cfg(feature = "v2")] fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { - todo!(); + Some(&self.payment_attempt) } } @@ -7435,9 +7433,8 @@ impl OperationSessionGetters for PaymentStatusData { todo!() } - // what is this address find out and not required remove this fn get_address(&self) -> &PaymentAddress { - todo!() + &self.payment_address } fn get_creds_identifier(&self) -> Option<&str> { @@ -7512,7 +7509,7 @@ impl OperationSessionGetters for PaymentStatusData { todo!() } - fn get_billing_address(&self) -> Option { + fn get_billing_address(&self) -> Option { todo!() } @@ -7540,7 +7537,6 @@ impl OperationSessionGetters for PaymentStatusData { todo!() } - #[cfg(feature = "v2")] fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { self.payment_attempt.as_ref() } diff --git a/crates/router/src/core/payments/connector_integration_v2_impls.rs b/crates/router/src/core/payments/connector_integration_v2_impls.rs index 8afd019d0801..7aeca55592a1 100644 --- a/crates/router/src/core/payments/connector_integration_v2_impls.rs +++ b/crates/router/src/core/payments/connector_integration_v2_impls.rs @@ -694,17 +694,14 @@ default_imp_for_new_connector_integration_payment!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -721,8 +718,6 @@ default_imp_for_new_connector_integration_payment!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -755,17 +750,14 @@ default_imp_for_new_connector_integration_refund!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -782,8 +774,6 @@ default_imp_for_new_connector_integration_refund!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -810,17 +800,14 @@ default_imp_for_new_connector_integration_connector_access_token!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -837,8 +824,6 @@ default_imp_for_new_connector_integration_connector_access_token!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -887,17 +872,14 @@ default_imp_for_new_connector_integration_accept_dispute!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -914,8 +896,6 @@ default_imp_for_new_connector_integration_accept_dispute!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -946,17 +926,14 @@ default_imp_for_new_connector_integration_defend_dispute!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -973,8 +950,6 @@ default_imp_for_new_connector_integration_defend_dispute!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -989,17 +964,14 @@ default_imp_for_new_connector_integration_submit_evidence!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1016,8 +988,6 @@ default_imp_for_new_connector_integration_submit_evidence!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1059,17 +1029,14 @@ default_imp_for_new_connector_integration_file_upload!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1086,8 +1053,6 @@ default_imp_for_new_connector_integration_file_upload!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1138,7 +1103,6 @@ default_imp_for_new_connector_integration_payouts!( connector::Forte, connector::Globalpay, connector::Globepay, - connector::Gocardless, connector::Gpayments, connector::Helcim, connector::Iatapay, @@ -1167,7 +1131,6 @@ default_imp_for_new_connector_integration_payouts!( connector::Payu, connector::Placetopay, connector::Powertranz, - connector::Prophetpay, connector::Rapyd, connector::Razorpay, connector::Redsys, @@ -1214,17 +1177,14 @@ default_imp_for_new_connector_integration_payouts_create!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1241,8 +1201,6 @@ default_imp_for_new_connector_integration_payouts_create!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1276,17 +1234,14 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1303,8 +1258,6 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1338,17 +1291,14 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1365,8 +1315,6 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1400,17 +1348,14 @@ default_imp_for_new_connector_integration_payouts_cancel!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1427,8 +1372,6 @@ default_imp_for_new_connector_integration_payouts_cancel!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1462,17 +1405,14 @@ default_imp_for_new_connector_integration_payouts_quote!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1489,8 +1429,6 @@ default_imp_for_new_connector_integration_payouts_quote!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1524,17 +1462,14 @@ default_imp_for_new_connector_integration_payouts_recipient!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1551,8 +1486,6 @@ default_imp_for_new_connector_integration_payouts_recipient!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1586,17 +1519,14 @@ default_imp_for_new_connector_integration_payouts_sync!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1613,8 +1543,6 @@ default_imp_for_new_connector_integration_payouts_sync!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1648,17 +1576,14 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1675,8 +1600,6 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1708,17 +1631,14 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1735,8 +1655,6 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1787,7 +1705,6 @@ default_imp_for_new_connector_integration_frm!( connector::Fiuu, connector::Globalpay, connector::Globepay, - connector::Gocardless, connector::Gpayments, connector::Helcim, connector::Iatapay, @@ -1816,7 +1733,6 @@ default_imp_for_new_connector_integration_frm!( connector::Payu, connector::Placetopay, connector::Powertranz, - connector::Prophetpay, connector::Rapyd, connector::Razorpay, connector::Redsys, @@ -1863,17 +1779,14 @@ default_imp_for_new_connector_integration_frm_sale!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1890,8 +1803,6 @@ default_imp_for_new_connector_integration_frm_sale!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1925,17 +1836,14 @@ default_imp_for_new_connector_integration_frm_checkout!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1952,8 +1860,6 @@ default_imp_for_new_connector_integration_frm_checkout!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1987,17 +1893,14 @@ default_imp_for_new_connector_integration_frm_transaction!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2014,8 +1917,6 @@ default_imp_for_new_connector_integration_frm_transaction!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2049,17 +1950,14 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2076,8 +1974,6 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2111,17 +2007,14 @@ default_imp_for_new_connector_integration_frm_record_return!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2138,8 +2031,6 @@ default_imp_for_new_connector_integration_frm_record_return!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2170,17 +2061,14 @@ default_imp_for_new_connector_integration_revoking_mandates!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2197,8 +2085,6 @@ default_imp_for_new_connector_integration_revoking_mandates!( connector::Payone, connector::Paypal, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index df319724bc40..45fe296e8edb 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -207,13 +207,10 @@ default_imp_for_complete_authorize!( connector::Adyenplatform, connector::Aci, connector::Adyen, - connector::Bamboraapac, connector::Bankofamerica, - connector::Boku, connector::Checkout, connector::Datatrans, connector::Ebanx, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -226,7 +223,6 @@ default_imp_for_complete_authorize!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -267,17 +263,14 @@ default_imp_for_webhook_source_verification!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, connector::Braintree, - connector::Boku, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -294,8 +287,6 @@ default_imp_for_webhook_source_verification!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -338,10 +329,8 @@ default_imp_for_create_customer!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, @@ -365,8 +354,6 @@ default_imp_for_create_customer!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -409,13 +396,10 @@ default_imp_for_connector_redirect_response!( connector::Adyenplatform, connector::Aci, connector::Adyen, - connector::Bamboraapac, connector::Bankofamerica, - connector::Boku, connector::Cybersource, connector::Datatrans, connector::Ebanx, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -427,8 +411,6 @@ default_imp_for_connector_redirect_response!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -566,16 +548,13 @@ default_imp_for_accept_dispute!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -593,8 +572,6 @@ default_imp_for_accept_dispute!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -658,16 +635,13 @@ default_imp_for_file_upload!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -684,8 +658,6 @@ default_imp_for_file_upload!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -727,16 +699,13 @@ default_imp_for_submit_evidence!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -753,8 +722,6 @@ default_imp_for_submit_evidence!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -796,16 +763,13 @@ default_imp_for_defend_dispute!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -822,8 +786,6 @@ default_imp_for_defend_dispute!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -881,10 +843,8 @@ default_imp_for_pre_processing_steps!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, @@ -903,8 +863,6 @@ default_imp_for_pre_processing_steps!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -930,7 +888,6 @@ default_imp_for_post_processing_steps!( connector::Adyen, connector::Bankofamerica, connector::Cybersource, - connector::Gocardless, connector::Nmi, connector::Nuvei, connector::Payme, @@ -939,9 +896,7 @@ default_imp_for_post_processing_steps!( connector::Trustpay, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, @@ -959,8 +914,6 @@ default_imp_for_post_processing_steps!( connector::Paybox, connector::Payone, connector::Placetopay, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -983,15 +936,12 @@ impl Payouts for connector::DummyConnector {} default_imp_for_payouts!( connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1007,8 +957,6 @@ default_imp_for_payouts!( connector::Payme, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1049,16 +997,13 @@ default_imp_for_payouts_create!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1075,8 +1020,6 @@ default_imp_for_payouts_create!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1118,17 +1061,14 @@ default_imp_for_payouts_retrieve!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1145,8 +1085,6 @@ default_imp_for_payouts_retrieve!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1192,16 +1130,13 @@ default_imp_for_payouts_eligibility!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1219,8 +1154,6 @@ default_imp_for_payouts_eligibility!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1261,15 +1194,12 @@ impl default_imp_for_payouts_fulfill!( connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1285,8 +1215,6 @@ default_imp_for_payouts_fulfill!( connector::Payme, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1327,16 +1255,13 @@ default_imp_for_payouts_cancel!( connector::Adyenplatform, connector::Aci, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1354,8 +1279,6 @@ default_imp_for_payouts_cancel!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1397,16 +1320,13 @@ default_imp_for_payouts_quote!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1424,8 +1344,6 @@ default_imp_for_payouts_quote!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1468,16 +1386,13 @@ default_imp_for_payouts_recipient!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1495,8 +1410,6 @@ default_imp_for_payouts_recipient!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1541,17 +1454,14 @@ default_imp_for_payouts_recipient_account!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1569,8 +1479,6 @@ default_imp_for_payouts_recipient_account!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Threedsecureio, @@ -1612,17 +1520,14 @@ default_imp_for_approve!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1640,8 +1545,6 @@ default_imp_for_approve!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1684,17 +1587,14 @@ default_imp_for_reject!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1712,8 +1612,6 @@ default_imp_for_reject!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -1853,17 +1751,14 @@ default_imp_for_frm_sale!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1881,8 +1776,6 @@ default_imp_for_frm_sale!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Stripe, connector::Threedsecureio, connector::Trustpay, @@ -1925,17 +1818,14 @@ default_imp_for_frm_checkout!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -1953,8 +1843,6 @@ default_imp_for_frm_checkout!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Stripe, connector::Threedsecureio, connector::Trustpay, @@ -1997,17 +1885,14 @@ default_imp_for_frm_transaction!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2025,8 +1910,6 @@ default_imp_for_frm_transaction!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Stripe, connector::Threedsecureio, connector::Trustpay, @@ -2069,17 +1952,14 @@ default_imp_for_frm_fulfillment!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2097,8 +1977,6 @@ default_imp_for_frm_fulfillment!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Stripe, connector::Threedsecureio, connector::Trustpay, @@ -2141,17 +2019,14 @@ default_imp_for_frm_record_return!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2169,8 +2044,6 @@ default_imp_for_frm_record_return!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Stripe, connector::Threedsecureio, connector::Trustpay, @@ -2211,16 +2084,13 @@ default_imp_for_incremental_authorization!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2238,8 +2108,6 @@ default_imp_for_incremental_authorization!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2279,16 +2147,13 @@ default_imp_for_revoking_mandates!( connector::Aci, connector::Adyen, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2305,8 +2170,6 @@ default_imp_for_revoking_mandates!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2513,17 +2376,14 @@ default_imp_for_authorize_session_token!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2540,8 +2400,6 @@ default_imp_for_authorize_session_token!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2582,17 +2440,14 @@ default_imp_for_calculate_tax!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2610,8 +2465,6 @@ default_imp_for_calculate_tax!( connector::Paypal, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2652,17 +2505,14 @@ default_imp_for_session_update!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2679,8 +2529,6 @@ default_imp_for_session_update!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, @@ -2721,17 +2569,14 @@ default_imp_for_post_session_tokens!( connector::Adyen, connector::Adyenplatform, connector::Authorizedotnet, - connector::Bamboraapac, connector::Bankofamerica, connector::Bluesnap, - connector::Boku, connector::Braintree, connector::Checkout, connector::Cybersource, connector::Datatrans, connector::Ebanx, connector::Globalpay, - connector::Gocardless, connector::Gpayments, connector::Iatapay, connector::Itaubank, @@ -2748,8 +2593,6 @@ default_imp_for_post_session_tokens!( connector::Payone, connector::Placetopay, connector::Plaid, - connector::Prophetpay, - connector::Rapyd, connector::Riskified, connector::Signifyd, connector::Stripe, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 219a4d90519b..e7de03804d12 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -19,7 +19,7 @@ use common_utils::{ MinorUnit, }, }; -use diesel_models::enums::{self}; +use diesel_models::enums; // TODO : Evaluate all the helper functions () use error_stack::{report, ResultExt}; use futures::future::Either; diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs index 850fa738cd84..8c003f54adf4 100644 --- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs +++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs @@ -16,6 +16,7 @@ use crate::{ PaymentData, }, }, + events::audit_events::{AuditEvent, AuditEventType}, routes::{app::ReqState, SessionState}, services, types::{ @@ -462,7 +463,7 @@ impl UpdateTracker, api::PaymentsRequest> for Comple async fn update_trackers<'b>( &'b self, state: &'b SessionState, - _req_state: ReqState, + req_state: ReqState, mut payment_data: PaymentData, _customer: Option, storage_scheme: storage_enums::MerchantStorageScheme, @@ -492,6 +493,12 @@ impl UpdateTracker, api::PaymentsRequest> for Comple .await .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + req_state + .event_context + .event(AuditEvent::new(AuditEventType::PaymentCompleteAuthorize)) + .with(payment_data.to_event()) + .emit(); + payment_data.payment_intent = updated_payment_intent; Ok((Box::new(self), payment_data)) } diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index b56260b407eb..4b4091b1c3a6 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -708,7 +708,8 @@ impl GetTracker, api::PaymentsRequest> for Pa .and_then(|pmd| pmd.payment_method_data.as_ref()) .and_then(|payment_method_data_billing| { payment_method_data_billing.get_billing_address() - }); + }) + .map(From::from); let unified_address = address.unify_with_payment_method_data_billing(payment_method_data_billing); diff --git a/crates/router/src/core/payments/operations/payment_confirm_intent.rs b/crates/router/src/core/payments/operations/payment_confirm_intent.rs index 5965bdc88503..05c901025655 100644 --- a/crates/router/src/core/payments/operations/payment_confirm_intent.rs +++ b/crates/router/src/core/payments/operations/payment_confirm_intent.rs @@ -228,11 +228,28 @@ impl GetTracker, PaymentsConfirmIntent .clone() .map(hyperswitch_domain_models::payment_method_data::PaymentMethodData::from); + let payment_address = hyperswitch_domain_models::payment_address::PaymentAddress::new( + payment_intent + .shipping_address + .clone() + .map(|address| address.into_inner()), + payment_intent + .billing_address + .clone() + .map(|address| address.into_inner()), + payment_attempt + .payment_method_billing_address + .clone() + .map(|address| address.into_inner()), + Some(true), + ); + let payment_data = PaymentConfirmData { flow: std::marker::PhantomData, payment_intent, payment_attempt, payment_method_data, + payment_address, }; let get_trackers_response = operations::GetTrackerResponse { payment_data }; diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs index 697c06603da0..30891e76e86f 100644 --- a/crates/router/src/core/payments/operations/payment_create.rs +++ b/crates/router/src/core/payments/operations/payment_create.rs @@ -566,7 +566,8 @@ impl GetTracker, api::PaymentsRequest> for Pa .and_then(|pmd| pmd.payment_method_data.as_ref()) .and_then(|payment_method_data_billing| { payment_method_data_billing.get_billing_address() - }); + }) + .map(From::from); let unified_address = address.unify_with_payment_method_data_billing(payment_method_data_billing); diff --git a/crates/router/src/core/payments/operations/payment_get.rs b/crates/router/src/core/payments/operations/payment_get.rs index a69c3187c781..f66186c7c571 100644 --- a/crates/router/src/core/payments/operations/payment_get.rs +++ b/crates/router/src/core/payments/operations/payment_get.rs @@ -163,10 +163,29 @@ impl GetTracker, PaymentsRetrieveReques let should_sync_with_connector = request.force_sync && payment_intent.status.should_force_sync_with_connector(); + // We need the address here to send it in the response + let payment_address = hyperswitch_domain_models::payment_address::PaymentAddress::new( + payment_intent + .shipping_address + .clone() + .map(|address| address.into_inner()), + payment_intent + .billing_address + .clone() + .map(|address| address.into_inner()), + payment_attempt + .as_ref() + .and_then(|payment_attempt| payment_attempt.payment_method_billing_address.as_ref()) + .cloned() + .map(|address| address.into_inner()), + Some(true), + ); + let payment_data = PaymentStatusData { flow: std::marker::PhantomData, payment_intent, payment_attempt, + payment_address, should_sync_with_connector, }; diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index e3f9ad5d9054..d77236c8a2bc 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -720,7 +720,7 @@ impl PostUpdateTracker, types::SdkPaymentsSessionUpd let shipping_address = payments_helpers::create_or_update_address_for_payment_by_request( db, - shipping_address.as_ref(), + shipping_address.map(From::from).as_ref(), payment_data.payment_intent.shipping_address_id.as_deref(), &payment_data.payment_intent.merchant_id, payment_data.payment_intent.customer_id.as_ref(), diff --git a/crates/router/src/core/payments/operations/tax_calculation.rs b/crates/router/src/core/payments/operations/tax_calculation.rs index 2d4054a60bed..c615e2eb1744 100644 --- a/crates/router/src/core/payments/operations/tax_calculation.rs +++ b/crates/router/src/core/payments/operations/tax_calculation.rs @@ -129,7 +129,7 @@ impl GetTracker, api::PaymentsDynamicTaxCalcu })?; let tax_data = payments::TaxData { - shipping_details: request.shipping.clone(), + shipping_details: request.shipping.clone().into(), payment_method_type: request.payment_method_type, }; @@ -403,7 +403,7 @@ impl UpdateTracker, api::PaymentsDynamicTaxCalculati let shipping_address = helpers::create_or_update_address_for_payment_by_request( state, - shipping_address.as_ref(), + shipping_address.map(From::from).as_ref(), payment_data.payment_intent.shipping_address_id.as_deref(), &payment_data.payment_intent.merchant_id, payment_data.payment_intent.customer_id.as_ref(), diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs index 28321529ef2d..76456c8dbc90 100644 --- a/crates/router/src/core/payments/routing.rs +++ b/crates/router/src/core/payments/routing.rs @@ -12,7 +12,6 @@ use api_models::routing as api_routing; use api_models::{ admin as admin_api, enums::{self as api_enums, CountryAlpha2}, - payments::Address, routing::ConnectorSelection, }; use diesel_models::enums as storage_enums; @@ -27,6 +26,7 @@ use euclid::{ use external_services::grpc_client::dynamic_routing::{ success_rate::CalSuccessRateResponse, SuccessBasedDynamicRouting, }; +use hyperswitch_domain_models::address::Address; use kgraph_utils::{ mca as mca_graph, transformers::{IntoContext, IntoDirValue}, @@ -1263,7 +1263,7 @@ pub async fn perform_success_based_routing( )?; if success_based_algo_ref.enabled_feature - == api_routing::SuccessBasedRoutingFeatures::DynamicConnectorSelection + == api_routing::DynamicRoutingFeatures::DynamicConnectorSelection { logger::debug!( "performing success_based_routing for profile {}", diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 14f64cab1535..efee99bb7a0e 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -80,7 +80,7 @@ pub async fn save_payment_method( payment_method_type: Option, key_store: &domain::MerchantKeyStore, billing_name: Option>, - payment_method_billing_address: Option<&api::Address>, + payment_method_billing_address: Option<&hyperswitch_domain_models::address::Address>, business_profile: &domain::Profile, mut original_connector_mandate_reference_id: Option, ) -> RouterResult diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 9e0557d5b3eb..fe70c3b71080 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -332,7 +332,7 @@ pub async fn construct_payment_router_data_for_authorize<'a>( .map(|description| description.get_string_repr()) .map(ToOwned::to_owned), // TODO: Create unified address - address: hyperswitch_domain_models::payment_address::PaymentAddress::default(), + address: payment_data.payment_address.clone(), auth_type: payment_data.payment_attempt.authentication_type, connector_meta_data: None, connector_wallets_details: None, @@ -433,7 +433,7 @@ pub async fn construct_router_data_for_psync<'a>( sync_type: types::SyncRequestType::SinglePaymentSync, payment_method_type: Some(attempt.payment_method_subtype), currency: payment_intent.amount_details.currency, - // TODO: Get the charges object from + // TODO: Get the charges object from feature metadata charges: None, payment_experience: None, }; @@ -655,30 +655,6 @@ pub async fn construct_payment_router_data_for_sdk_session<'a>( Ok(router_data) } -#[cfg(feature = "v2")] -#[instrument(skip_all)] -#[allow(clippy::too_many_arguments)] -pub async fn construct_payment_router_data<'a, F, T>( - state: &'a SessionState, - payment_data: PaymentData, - connector_id: &str, - merchant_account: &domain::MerchantAccount, - _key_store: &domain::MerchantKeyStore, - customer: &'a Option, - merchant_connector_account: &helpers::MerchantConnectorAccountType, - merchant_recipient_data: Option, - header_payload: Option, -) -> RouterResult> -where - T: TryFrom>, - types::RouterData: Feature, - F: Clone, - error_stack::Report: - From<>>::Error>, -{ - todo!() -} - #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] #[instrument(skip_all)] #[allow(clippy::too_many_arguments)] @@ -1109,6 +1085,7 @@ where Ok(services::ApplicationResponse::JsonWithHeaders(( Self { id: payment_intent.id.clone(), + profile_id: payment_intent.profile_id.clone(), status: payment_intent.status, amount_details: api_models::payments::AmountDetailsResponse::foreign_from( payment_intent.amount_details.clone(), @@ -1211,6 +1188,17 @@ where .clone() .map(api_models::payments::ErrorDetails::foreign_from); + let payment_address = payment_data.get_address(); + + let payment_method_data = + Some(api_models::payments::PaymentMethodDataResponseWithBilling { + payment_method_data: None, + billing: payment_address + .get_request_payment_method_billing() + .cloned() + .map(From::from), + }); + // TODO: Add support for other next actions, currently only supporting redirect to url let redirect_to_url = payment_intent .create_start_redirection_url(base_url, merchant_account.publishable_key.clone())?; @@ -1226,7 +1214,7 @@ where connector, client_secret: payment_intent.client_secret.clone(), created: payment_intent.created_at, - payment_method_data: None, + payment_method_data, payment_method_type: payment_attempt.payment_method_type, payment_method_subtype: payment_attempt.payment_method_subtype, next_action, @@ -1281,14 +1269,30 @@ where .and_then(|payment_attempt| payment_attempt.error.clone()) .map(api_models::payments::ErrorDetails::foreign_from); + let payment_address = payment_data.get_address(); + + let payment_method_data = + Some(api_models::payments::PaymentMethodDataResponseWithBilling { + payment_method_data: None, + billing: payment_address + .get_request_payment_method_billing() + .cloned() + .map(From::from), + }); + let response = Self { id: payment_intent.id.clone(), status: payment_intent.status, amount, connector, + billing: payment_address + .get_payment_billing() + .cloned() + .map(From::from), + shipping: payment_address.get_shipping().cloned().map(From::from), client_secret: payment_intent.client_secret.clone(), created: payment_intent.created_at, - payment_method_data: None, + payment_method_data, payment_method_type: payment_attempt.map(|attempt| attempt.payment_method_type), payment_method_subtype: payment_attempt.map(|attempt| attempt.payment_method_subtype), connector_transaction_id: payment_attempt @@ -1631,7 +1635,8 @@ where billing: payment_data .get_address() .get_request_payment_method_billing() - .cloned(), + .cloned() + .map(From::from), }); let mut headers = connector_http_status_code @@ -1993,8 +1998,16 @@ where payment_method: payment_attempt.payment_method, payment_method_data: payment_method_data_response, payment_token: payment_attempt.payment_token, - shipping: payment_data.get_address().get_shipping().cloned(), - billing: payment_data.get_address().get_payment_billing().cloned(), + shipping: payment_data + .get_address() + .get_shipping() + .cloned() + .map(From::from), + billing: payment_data + .get_address() + .get_payment_billing() + .cloned() + .map(From::from), order_details: payment_intent.order_details, email: customer .as_ref() @@ -3513,10 +3526,10 @@ impl currency: intent_amount_details.currency, shipping_cost: attempt_amount_details.shipping_cost, order_tax_amount: attempt_amount_details.order_tax_amount, - skip_external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( + external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( intent_amount_details.skip_external_tax_calculation, ), - skip_surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( + surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( intent_amount_details.skip_surcharge_calculation, ), surcharge_amount: attempt_amount_details.surcharge_amount, @@ -3556,10 +3569,10 @@ impl .tax_details .as_ref() .and_then(|tax_details| tax_details.get_default_tax_amount())), - skip_external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( + external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( intent_amount_details.skip_external_tax_calculation, ), - skip_surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( + surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( intent_amount_details.skip_surcharge_calculation, ), surcharge_amount: attempt_amount_details @@ -3616,10 +3629,10 @@ impl ForeignFrom order_tax_amount: amount_details.tax_details.and_then(|tax_details| { tax_details.default.map(|default| default.order_tax_amount) }), - skip_external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( + external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( amount_details.skip_external_tax_calculation, ), - skip_surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( + surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( amount_details.skip_surcharge_calculation, ), surcharge_amount: amount_details.surcharge_amount, diff --git a/crates/router/src/core/payout_link.rs b/crates/router/src/core/payout_link.rs index 31e65e8e0a79..223db5b9f908 100644 --- a/crates/router/src/core/payout_link.rs +++ b/crates/router/src/core/payout_link.rs @@ -214,7 +214,10 @@ pub async fn initiate_payout_link( }); let required_field_override = api::RequiredFieldsOverrideRequest { - billing: address.as_ref().map(From::from), + billing: address + .as_ref() + .map(hyperswitch_domain_models::address::Address::from) + .map(From::from), }; let enabled_payment_methods_with_required_fields = ForeignFrom::foreign_from(( diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs index adf3c51fd80b..d239638c0c60 100644 --- a/crates/router/src/core/payouts.rs +++ b/crates/router/src/core/payouts.rs @@ -852,7 +852,9 @@ pub async fn payouts_list_core( logger::warn!(?err, err_msg); }) .ok() - .map(payment_enums::Address::foreign_from) + .as_ref() + .map(hyperswitch_domain_models::address::Address::from) + .map(payment_enums::Address::from) }); pi_pa_tuple_vec.push(( @@ -2354,7 +2356,10 @@ pub async fn response_handler( let billing_address = payout_data.billing_address.to_owned(); let customer_details = payout_data.customer_details.to_owned(); let customer_id = payouts.customer_id; - let billing = billing_address.as_ref().map(From::from); + let billing = billing_address + .as_ref() + .map(hyperswitch_domain_models::address::Address::from) + .map(From::from); let translated_unified_message = helpers::get_translated_unified_code_and_message( state, diff --git a/crates/router/src/core/pm_auth/transformers.rs b/crates/router/src/core/pm_auth/transformers.rs index d516cab62fe7..b8a855f5332f 100644 --- a/crates/router/src/core/pm_auth/transformers.rs +++ b/crates/router/src/core/pm_auth/transformers.rs @@ -1,4 +1,4 @@ -use pm_auth::types::{self as pm_auth_types}; +use pm_auth::types as pm_auth_types; use crate::{core::errors, types, types::transformers::ForeignTryFrom}; diff --git a/crates/router/src/core/recon.rs b/crates/router/src/core/recon.rs index 521c978e3c2b..13cf4c488ec5 100644 --- a/crates/router/src/core/recon.rs +++ b/crates/router/src/core/recon.rs @@ -1,100 +1,113 @@ use api_models::recon as recon_api; +#[cfg(feature = "email")] use common_utils::ext_traits::AsyncExt; use error_stack::ResultExt; +#[cfg(feature = "email")] use masking::{ExposeInterface, PeekInterface, Secret}; +#[cfg(feature = "email")] +use crate::{consts, services::email::types as email_types, types::domain}; use crate::{ - consts, - core::errors::{self, RouterResponse, UserErrors}, - services::{api as service_api, authentication, email::types as email_types}, + core::errors::{self, RouterResponse, UserErrors, UserResponse}, + services::{api as service_api, authentication}, types::{ api::{self as api_types, enums}, - domain, storage, + storage, transformers::ForeignTryFrom, }, SessionState, }; +#[allow(unused_variables)] pub async fn send_recon_request( state: SessionState, auth_data: authentication::AuthenticationDataWithUser, ) -> RouterResponse { - let user_in_db = &auth_data.user; - let merchant_id = auth_data.merchant_account.get_id().clone(); - - let user_email = user_in_db.email.clone(); - let email_contents = email_types::ProFeatureRequest { - feature_name: consts::RECON_FEATURE_TAG.to_string(), - merchant_id: merchant_id.clone(), - user_name: domain::UserName::new(user_in_db.name.clone()) - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to form username")?, - user_email: domain::UserEmail::from_pii_email(user_email.clone()) + #[cfg(not(feature = "email"))] + return Ok(service_api::ApplicationResponse::Json( + recon_api::ReconStatusResponse { + recon_status: enums::ReconStatus::NotRequested, + }, + )); + + #[cfg(feature = "email")] + { + let user_in_db = &auth_data.user; + let merchant_id = auth_data.merchant_account.get_id().clone(); + + let user_email = user_in_db.email.clone(); + let email_contents = email_types::ProFeatureRequest { + feature_name: consts::RECON_FEATURE_TAG.to_string(), + merchant_id: merchant_id.clone(), + user_name: domain::UserName::new(user_in_db.name.clone()) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to form username")?, + user_email: domain::UserEmail::from_pii_email(user_email.clone()) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to convert recipient's email to UserEmail")?, + recipient_email: domain::UserEmail::from_pii_email( + state.conf.email.recon_recipient_email.clone(), + ) .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to convert recipient's email to UserEmail")?, - recipient_email: domain::UserEmail::from_pii_email( - state.conf.email.recon_recipient_email.clone(), - ) - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to convert recipient's email to UserEmail")?, - settings: state.conf.clone(), - subject: format!( - "{} {}", - consts::EMAIL_SUBJECT_DASHBOARD_FEATURE_REQUEST, - user_email.expose().peek() - ), - }; + subject: format!( + "{} {}", + consts::EMAIL_SUBJECT_DASHBOARD_FEATURE_REQUEST, + user_email.expose().peek() + ), + }; + state + .email_client + .compose_and_send_email( + Box::new(email_contents), + state.conf.proxy.https_url.as_ref(), + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to compose and send email for ProFeatureRequest [Recon]") + .async_and_then(|_| async { + let updated_merchant_account = storage::MerchantAccountUpdate::ReconUpdate { + recon_status: enums::ReconStatus::Requested, + }; + let db = &*state.store; + let key_manager_state = &(&state).into(); - state - .email_client - .compose_and_send_email( - Box::new(email_contents), - state.conf.proxy.https_url.as_ref(), - ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to compose and send email for ProFeatureRequest [Recon]") - .async_and_then(|_| async { - let updated_merchant_account = storage::MerchantAccountUpdate::ReconUpdate { - recon_status: enums::ReconStatus::Requested, - }; - let db = &*state.store; - let key_manager_state = &(&state).into(); - - let response = db - .update_merchant( - key_manager_state, - auth_data.merchant_account, - updated_merchant_account, - &auth_data.key_store, - ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable_lazy(|| { - format!("Failed while updating merchant's recon status: {merchant_id:?}") - })?; - - Ok(service_api::ApplicationResponse::Json( - recon_api::ReconStatusResponse { - recon_status: response.recon_status, - }, - )) - }) - .await + let response = db + .update_merchant( + key_manager_state, + auth_data.merchant_account, + updated_merchant_account, + &auth_data.key_store, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable_lazy(|| { + format!("Failed while updating merchant's recon status: {merchant_id:?}") + })?; + + Ok(service_api::ApplicationResponse::Json( + recon_api::ReconStatusResponse { + recon_status: response.recon_status, + }, + )) + }) + .await + } } pub async fn generate_recon_token( state: SessionState, - user: authentication::UserFromToken, + user_with_role: authentication::UserFromTokenWithRoleInfo, ) -> RouterResponse { - let token = authentication::AuthToken::new_token( + let user = user_with_role.user; + let token = authentication::ReconToken::new_token( user.user_id.clone(), user.merchant_id.clone(), - user.role_id.clone(), &state.conf, user.org_id.clone(), user.profile_id.clone(), user.tenant_id, + user_with_role.role_info, ) .await .change_context(errors::ApiErrorResponse::InternalServerError) @@ -138,29 +151,37 @@ pub async fn recon_merchant_account_update( format!("Failed while updating merchant's recon status: {merchant_id:?}") })?; - let user_email = &req.user_email.clone(); - let email_contents = email_types::ReconActivation { - recipient_email: domain::UserEmail::from_pii_email(user_email.clone()) - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to convert recipient's email to UserEmail from pii::Email")?, - user_name: domain::UserName::new(Secret::new("HyperSwitch User".to_string())) - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to form username")?, - settings: state.conf.clone(), - subject: consts::EMAIL_SUBJECT_APPROVAL_RECON_REQUEST, - }; - - if req.recon_status == enums::ReconStatus::Active { - let _ = state - .email_client - .compose_and_send_email( - Box::new(email_contents), - state.conf.proxy.https_url.as_ref(), - ) - .await - .change_context(UserErrors::InternalServerError) - .attach_printable("Failed to compose and send email for ReconActivation") - .is_ok(); + #[cfg(feature = "email")] + { + let user_email = &req.user_email.clone(); + let email_contents = email_types::ReconActivation { + recipient_email: domain::UserEmail::from_pii_email(user_email.clone()) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "Failed to convert recipient's email to UserEmail from pii::Email", + )?, + user_name: domain::UserName::new(Secret::new("HyperSwitch User".to_string())) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to form username")?, + subject: consts::EMAIL_SUBJECT_APPROVAL_RECON_REQUEST, + }; + if req.recon_status == enums::ReconStatus::Active { + let _ = state + .email_client + .compose_and_send_email( + Box::new(email_contents), + state.conf.proxy.https_url.as_ref(), + ) + .await + .inspect_err(|err| { + router_env::logger::error!( + "Failed to compose and send email notifying them of recon activation: {}", + err + ) + }) + .change_context(UserErrors::InternalServerError) + .attach_printable("Failed to compose and send email for ReconActivation"); + } } Ok(service_api::ApplicationResponse::Json( @@ -170,3 +191,34 @@ pub async fn recon_merchant_account_update( })?, )) } + +pub async fn verify_recon_token( + state: SessionState, + user_with_role: authentication::UserFromTokenWithRoleInfo, +) -> UserResponse { + let user = user_with_role.user; + let user_in_db = user + .get_user_from_db(&state) + .await + .attach_printable_lazy(|| { + format!( + "Failed to fetch the user from DB for user_id - {}", + user.user_id + ) + })?; + + let acl = user_with_role.role_info.get_recon_acl(); + let optional_acl_str = serde_json::to_string(&acl) + .inspect_err(|err| router_env::logger::error!("Failed to serialize acl to string: {}", err)) + .change_context(UserErrors::InternalServerError) + .attach_printable("Failed to serialize acl to string. Using empty ACL") + .ok(); + + Ok(service_api::ApplicationResponse::Json( + recon_api::VerifyTokenResponse { + merchant_id: user.merchant_id.to_owned(), + user_email: user_in_db.0.email, + acl: optional_acl_str, + }, + )) +} diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index c706d8854af5..ebc4c926599a 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -914,7 +914,6 @@ pub async fn validate_and_create_refund( /// If payment-id is provided, lists all the refunds associated with that particular payment-id /// If payment-id is not provided, lists the refunds associated with that particular merchant - to the limit specified,if no limits given, it is 10 by default - #[instrument(skip_all)] #[cfg(feature = "olap")] pub async fn refund_list( diff --git a/crates/router/src/core/routing.rs b/crates/router/src/core/routing.rs index 348f5229b756..9318e0c5b9fa 100644 --- a/crates/router/src/core/routing.rs +++ b/crates/router/src/core/routing.rs @@ -452,6 +452,16 @@ pub async fn link_routing_config( }, enabled_feature: _ }) if id == &algorithm_id + ) || matches!( + dynamic_routing_ref.elimination_routing_algorithm, + Some(routing::EliminationRoutingAlgorithm { + algorithm_id_with_timestamp: + routing_types::DynamicAlgorithmWithTimestamp { + algorithm_id: Some(ref id), + timestamp: _ + }, + enabled_feature: _ + }) if id == &algorithm_id ), || { Err(errors::ApiErrorResponse::PreconditionFailed { @@ -470,7 +480,9 @@ pub async fn link_routing_config( "missing success_based_algorithm in dynamic_algorithm_ref from business_profile table", )? .enabled_feature, + routing_types::DynamicRoutingType::SuccessRateBasedRouting, ); + helpers::update_business_profile_active_dynamic_algorithm_ref( db, key_manager_state, @@ -1185,13 +1197,16 @@ pub async fn update_default_routing_config_for_profile( )) } +// Toggle the specific routing type as well as add the default configs in RoutingAlgorithm table +// and update the same in business profile table. #[cfg(all(feature = "v1", feature = "dynamic_routing"))] -pub async fn toggle_success_based_routing( +pub async fn toggle_specific_dynamic_routing( state: SessionState, merchant_account: domain::MerchantAccount, key_store: domain::MerchantKeyStore, - feature_to_enable: routing::SuccessBasedRoutingFeatures, + feature_to_enable: routing::DynamicRoutingFeatures, profile_id: common_utils::id_type::ProfileId, + dynamic_routing_type: routing::DynamicRoutingType, ) -> RouterResponse { metrics::ROUTING_CREATE_REQUEST_RECEIVED.add( &metrics::CONTEXT, @@ -1214,170 +1229,44 @@ pub async fn toggle_success_based_routing( id: profile_id.get_string_repr().to_owned(), })?; - let mut success_based_dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef = - business_profile - .dynamic_routing_algorithm - .clone() - .map(|val| val.parse_value("DynamicRoutingAlgorithmRef")) - .transpose() - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable( - "unable to deserialize dynamic routing algorithm ref from business profile", - )? - .unwrap_or_default(); + let dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef = business_profile + .dynamic_routing_algorithm + .clone() + .map(|val| val.parse_value("DynamicRoutingAlgorithmRef")) + .transpose() + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "unable to deserialize dynamic routing algorithm ref from business profile", + )? + .unwrap_or_default(); match feature_to_enable { - routing::SuccessBasedRoutingFeatures::Metrics - | routing::SuccessBasedRoutingFeatures::DynamicConnectorSelection => { - if let Some(ref mut algo_with_timestamp) = - success_based_dynamic_routing_algo_ref.success_based_algorithm - { - match algo_with_timestamp - .algorithm_id_with_timestamp - .algorithm_id - .clone() - { - Some(algorithm_id) => { - // algorithm is already present in profile - if algo_with_timestamp.enabled_feature == feature_to_enable { - // algorithm already has the required feature - Err(errors::ApiErrorResponse::PreconditionFailed { - message: "Success rate based routing is already enabled" - .to_string(), - })? - } else { - // enable the requested feature for the algorithm - algo_with_timestamp.update_enabled_features(feature_to_enable); - let record = db - .find_routing_algorithm_by_profile_id_algorithm_id( - business_profile.get_id(), - &algorithm_id, - ) - .await - .to_not_found_response( - errors::ApiErrorResponse::ResourceIdNotFound, - )?; - let response = record.foreign_into(); - helpers::update_business_profile_active_dynamic_algorithm_ref( - db, - key_manager_state, - &key_store, - business_profile, - success_based_dynamic_routing_algo_ref, - ) - .await?; - - metrics::ROUTING_CREATE_SUCCESS_RESPONSE.add( - &metrics::CONTEXT, - 1, - &add_attributes([( - "profile_id", - profile_id.get_string_repr().to_owned(), - )]), - ); - Ok(service_api::ApplicationResponse::Json(response)) - } - } - None => { - // algorithm isn't present in profile - helpers::default_success_based_routing_setup( - &state, - key_store, - business_profile, - feature_to_enable, - merchant_account.get_id().to_owned(), - success_based_dynamic_routing_algo_ref, - ) - .await - } - } - } else { - // algorithm isn't present in profile - helpers::default_success_based_routing_setup( - &state, - key_store, - business_profile, - feature_to_enable, - merchant_account.get_id().to_owned(), - success_based_dynamic_routing_algo_ref, - ) - .await - } + routing::DynamicRoutingFeatures::Metrics + | routing::DynamicRoutingFeatures::DynamicConnectorSelection => { + // occurs when algorithm is already present in the db + // 1. If present with same feature then return response as already enabled + // 2. Else update the feature and persist the same on db + // 3. If not present in db then create a new default entry + helpers::enable_dynamic_routing_algorithm( + &state, + key_store, + business_profile, + feature_to_enable, + dynamic_routing_algo_ref, + dynamic_routing_type, + ) + .await } - routing::SuccessBasedRoutingFeatures::None => { - // disable success based routing for the requested profile - let timestamp = common_utils::date_time::now_unix_timestamp(); - match success_based_dynamic_routing_algo_ref.success_based_algorithm { - Some(algorithm_ref) => { - if let Some(algorithm_id) = - algorithm_ref.algorithm_id_with_timestamp.algorithm_id - { - let dynamic_routing_algorithm = routing_types::DynamicRoutingAlgorithmRef { - success_based_algorithm: Some(routing::SuccessBasedAlgorithm { - algorithm_id_with_timestamp: - routing_types::DynamicAlgorithmWithTimestamp { - algorithm_id: None, - timestamp, - }, - enabled_feature: routing::SuccessBasedRoutingFeatures::None, - }), - }; - - // redact cache for success based routing configs - let cache_key = format!( - "{}_{}", - business_profile.get_id().get_string_repr(), - algorithm_id.get_string_repr() - ); - let cache_entries_to_redact = - vec![cache::CacheKind::SuccessBasedDynamicRoutingCache( - cache_key.into(), - )]; - let _ = cache::publish_into_redact_channel( - state.store.get_cache_store().as_ref(), - cache_entries_to_redact, - ) - .await - .change_context(errors::ApiErrorResponse::InternalServerError) - .attach_printable("unable to publish into the redact channel for evicting the success based routing config cache")?; - - let record = db - .find_routing_algorithm_by_profile_id_algorithm_id( - business_profile.get_id(), - &algorithm_id, - ) - .await - .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?; - let response = record.foreign_into(); - helpers::update_business_profile_active_dynamic_algorithm_ref( - db, - key_manager_state, - &key_store, - business_profile, - dynamic_routing_algorithm, - ) - .await?; - - metrics::ROUTING_UNLINK_CONFIG_SUCCESS_RESPONSE.add( - &metrics::CONTEXT, - 1, - &add_attributes([( - "profile_id", - profile_id.get_string_repr().to_owned(), - )]), - ); - - Ok(service_api::ApplicationResponse::Json(response)) - } else { - Err(errors::ApiErrorResponse::PreconditionFailed { - message: "Algorithm is already inactive".to_string(), - })? - } - } - None => Err(errors::ApiErrorResponse::PreconditionFailed { - message: "Success rate based routing is already disabled".to_string(), - })?, - } + routing::DynamicRoutingFeatures::None => { + // disable specific dynamic routing for the requested profile + helpers::disable_dynamic_routing_algorithm( + &state, + key_store, + business_profile, + dynamic_routing_algo_ref, + dynamic_routing_type, + ) + .await } } } diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs index 264328796c8b..9dc56b8bd0a7 100644 --- a/crates/router/src/core/routing/helpers.rs +++ b/crates/router/src/core/routing/helpers.rs @@ -26,6 +26,8 @@ use router_env::{instrument, metrics::add_attributes, tracing}; use rustc_hash::FxHashSet; use storage_impl::redis::cache; +#[cfg(all(feature = "dynamic_routing", feature = "v1"))] +use crate::db::errors::StorageErrorExt; #[cfg(feature = "v2")] use crate::types::domain::MerchantConnectorAccount; use crate::{ @@ -39,6 +41,8 @@ use crate::{ use crate::{core::metrics as core_metrics, routes::metrics, types::transformers::ForeignInto}; pub const SUCCESS_BASED_DYNAMIC_ROUTING_ALGORITHM: &str = "Success rate based dynamic routing algorithm"; +pub const ELIMINATION_BASED_DYNAMIC_ROUTING_ALGORITHM: &str = + "Elimination based dynamic routing algorithm"; /// Provides us with all the configured configs of the Merchant in the ascending time configured /// manner and chooses the first of them @@ -263,9 +267,9 @@ pub async fn update_business_profile_active_dynamic_algorithm_ref( key_manager_state: &KeyManagerState, merchant_key_store: &domain::MerchantKeyStore, current_business_profile: domain::Profile, - dynamic_routing_algorithm: routing_types::DynamicRoutingAlgorithmRef, + dynamic_routing_algorithm_ref: routing_types::DynamicRoutingAlgorithmRef, ) -> RouterResult<()> { - let ref_val = dynamic_routing_algorithm + let ref_val = dynamic_routing_algorithm_ref .encode_to_value() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to convert dynamic routing ref to value")?; @@ -356,7 +360,7 @@ impl MerchantConnectorAccounts { } #[cfg(feature = "v2")] -impl<'h> RoutingAlgorithmHelpers<'h> { +impl RoutingAlgorithmHelpers<'_> { fn connector_choice( &self, choice: &routing_types::RoutableConnectorChoice, @@ -662,7 +666,7 @@ pub async fn push_metrics_with_update_window_for_success_based_routing( .ok_or(errors::ApiErrorResponse::InternalServerError) .attach_printable("success_based_algorithm not found in dynamic_routing_algorithm from business_profile table")?; - if success_based_algo_ref.enabled_feature != routing_types::SuccessBasedRoutingFeatures::None { + if success_based_algo_ref.enabled_feature != routing_types::DynamicRoutingFeatures::None { let client = state .grpc_client .dynamic_routing @@ -912,34 +916,303 @@ pub fn generate_tenant_business_profile_id( format!("{}:{}", redis_key_prefix, business_profile_id) } -/// default config setup for success_based_routing +#[cfg(all(feature = "v1", feature = "dynamic_routing"))] +pub async fn disable_dynamic_routing_algorithm( + state: &SessionState, + key_store: domain::MerchantKeyStore, + business_profile: domain::Profile, + dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef, + dynamic_routing_type: routing_types::DynamicRoutingType, +) -> RouterResult> { + let db = state.store.as_ref(); + let key_manager_state = &state.into(); + let timestamp = common_utils::date_time::now_unix_timestamp(); + let profile_id = business_profile + .get_id() + .clone() + .get_string_repr() + .to_owned(); + let (algorithm_id, dynamic_routing_algorithm, cache_entries_to_redact) = + match dynamic_routing_type { + routing_types::DynamicRoutingType::SuccessRateBasedRouting => { + let Some(algorithm_ref) = dynamic_routing_algo_ref.success_based_algorithm else { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Success rate based routing is already disabled".to_string(), + })? + }; + let Some(algorithm_id) = algorithm_ref.algorithm_id_with_timestamp.algorithm_id + else { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Algorithm is already inactive".to_string(), + })? + }; + + let cache_key = format!( + "{}_{}", + business_profile.get_id().get_string_repr(), + algorithm_id.get_string_repr() + ); + let cache_entries_to_redact = + vec![cache::CacheKind::SuccessBasedDynamicRoutingCache( + cache_key.into(), + )]; + ( + algorithm_id, + routing_types::DynamicRoutingAlgorithmRef { + success_based_algorithm: Some(routing_types::SuccessBasedAlgorithm { + algorithm_id_with_timestamp: + routing_types::DynamicAlgorithmWithTimestamp { + algorithm_id: None, + timestamp, + }, + enabled_feature: routing_types::DynamicRoutingFeatures::None, + }), + elimination_routing_algorithm: dynamic_routing_algo_ref + .elimination_routing_algorithm, + }, + cache_entries_to_redact, + ) + } + routing_types::DynamicRoutingType::EliminationRouting => { + let Some(algorithm_ref) = dynamic_routing_algo_ref.elimination_routing_algorithm + else { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Elimination routing is already disabled".to_string(), + })? + }; + let Some(algorithm_id) = algorithm_ref.algorithm_id_with_timestamp.algorithm_id + else { + Err(errors::ApiErrorResponse::PreconditionFailed { + message: "Algorithm is already inactive".to_string(), + })? + }; + let cache_key = format!( + "{}_{}", + business_profile.get_id().get_string_repr(), + algorithm_id.get_string_repr() + ); + let cache_entries_to_redact = + vec![cache::CacheKind::EliminationBasedDynamicRoutingCache( + cache_key.into(), + )]; + ( + algorithm_id, + routing_types::DynamicRoutingAlgorithmRef { + success_based_algorithm: dynamic_routing_algo_ref.success_based_algorithm, + elimination_routing_algorithm: Some( + routing_types::EliminationRoutingAlgorithm { + algorithm_id_with_timestamp: + routing_types::DynamicAlgorithmWithTimestamp { + algorithm_id: None, + timestamp, + }, + enabled_feature: routing_types::DynamicRoutingFeatures::None, + }, + ), + }, + cache_entries_to_redact, + ) + } + }; + + // redact cache for dynamic routing config + let _ = cache::publish_into_redact_channel( + state.store.get_cache_store().as_ref(), + cache_entries_to_redact, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "unable to publish into the redact channel for evicting the dynamic routing config cache", + )?; + + let record = db + .find_routing_algorithm_by_profile_id_algorithm_id(business_profile.get_id(), &algorithm_id) + .await + .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?; + let response = record.foreign_into(); + update_business_profile_active_dynamic_algorithm_ref( + db, + key_manager_state, + &key_store, + business_profile, + dynamic_routing_algorithm, + ) + .await?; + + core_metrics::ROUTING_UNLINK_CONFIG_SUCCESS_RESPONSE.add( + &metrics::CONTEXT, + 1, + &add_attributes([("profile_id", profile_id)]), + ); + + Ok(ApplicationResponse::Json(response)) +} + +#[cfg(all(feature = "v1", feature = "dynamic_routing"))] +pub async fn enable_dynamic_routing_algorithm( + state: &SessionState, + key_store: domain::MerchantKeyStore, + business_profile: domain::Profile, + feature_to_enable: routing_types::DynamicRoutingFeatures, + dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef, + dynamic_routing_type: routing_types::DynamicRoutingType, +) -> RouterResult> { + let dynamic_routing = dynamic_routing_algo_ref.clone(); + match dynamic_routing_type { + routing_types::DynamicRoutingType::SuccessRateBasedRouting => { + enable_specific_routing_algorithm( + state, + key_store, + business_profile, + feature_to_enable, + dynamic_routing_algo_ref, + dynamic_routing_type, + dynamic_routing.success_based_algorithm, + ) + .await + } + routing_types::DynamicRoutingType::EliminationRouting => { + enable_specific_routing_algorithm( + state, + key_store, + business_profile, + feature_to_enable, + dynamic_routing_algo_ref, + dynamic_routing_type, + dynamic_routing.elimination_routing_algorithm, + ) + .await + } + } +} + +#[cfg(all(feature = "v1", feature = "dynamic_routing"))] +pub async fn enable_specific_routing_algorithm( + state: &SessionState, + key_store: domain::MerchantKeyStore, + business_profile: domain::Profile, + feature_to_enable: routing_types::DynamicRoutingFeatures, + mut dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef, + dynamic_routing_type: routing_types::DynamicRoutingType, + algo_type: Option, +) -> RouterResult> +where + A: routing_types::DynamicRoutingAlgoAccessor + Clone + std::fmt::Debug, +{ + // Algorithm wasn't created yet + let Some(mut algo_type) = algo_type else { + return default_specific_dynamic_routing_setup( + state, + key_store, + business_profile, + feature_to_enable, + dynamic_routing_algo_ref, + dynamic_routing_type, + ) + .await; + }; + + // Algorithm was in disabled state + let Some(algo_type_algorithm_id) = algo_type + .clone() + .get_algorithm_id_with_timestamp() + .algorithm_id + else { + return default_specific_dynamic_routing_setup( + state, + key_store, + business_profile, + feature_to_enable, + dynamic_routing_algo_ref, + dynamic_routing_type, + ) + .await; + }; + let db = state.store.as_ref(); + let profile_id = business_profile.get_id().clone(); + let algo_type_enabled_features = algo_type.get_enabled_features(); + if *algo_type_enabled_features == feature_to_enable { + // algorithm already has the required feature + return Err(errors::ApiErrorResponse::PreconditionFailed { + message: format!("{} is already enabled", dynamic_routing_type), + } + .into()); + }; + *algo_type_enabled_features = feature_to_enable.clone(); + dynamic_routing_algo_ref + .update_specific_ref(dynamic_routing_type.clone(), feature_to_enable.clone()); + update_business_profile_active_dynamic_algorithm_ref( + db, + &state.into(), + &key_store, + business_profile, + dynamic_routing_algo_ref.clone(), + ) + .await?; + + let routing_algorithm = db + .find_routing_algorithm_by_profile_id_algorithm_id(&profile_id, &algo_type_algorithm_id) + .await + .to_not_found_response(errors::ApiErrorResponse::ResourceIdNotFound)?; + let updated_routing_record = routing_algorithm.foreign_into(); + core_metrics::ROUTING_CREATE_SUCCESS_RESPONSE.add( + &metrics::CONTEXT, + 1, + &add_attributes([("profile_id", profile_id.get_string_repr().to_owned())]), + ); + Ok(ApplicationResponse::Json(updated_routing_record)) +} + #[cfg(feature = "v1")] #[instrument(skip_all)] -pub async fn default_success_based_routing_setup( +pub async fn default_specific_dynamic_routing_setup( state: &SessionState, key_store: domain::MerchantKeyStore, business_profile: domain::Profile, - feature_to_enable: routing_types::SuccessBasedRoutingFeatures, - merchant_id: id_type::MerchantId, - mut success_based_dynamic_routing_algo: routing_types::DynamicRoutingAlgorithmRef, + feature_to_enable: routing_types::DynamicRoutingFeatures, + mut dynamic_routing_algo_ref: routing_types::DynamicRoutingAlgorithmRef, + dynamic_routing_type: routing_types::DynamicRoutingType, ) -> RouterResult> { let db = state.store.as_ref(); let key_manager_state = &state.into(); - let profile_id = business_profile.get_id().to_owned(); - let default_success_based_routing_config = routing_types::SuccessBasedRoutingConfig::default(); + let profile_id = business_profile.get_id().clone(); + let merchant_id = business_profile.merchant_id.clone(); let algorithm_id = common_utils::generate_routing_id_of_default_length(); let timestamp = common_utils::date_time::now(); - let algo = routing_algorithm::RoutingAlgorithm { - algorithm_id: algorithm_id.clone(), - profile_id: profile_id.clone(), - merchant_id, - name: SUCCESS_BASED_DYNAMIC_ROUTING_ALGORITHM.to_string(), - description: None, - kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic, - algorithm_data: serde_json::json!(default_success_based_routing_config), - created_at: timestamp, - modified_at: timestamp, - algorithm_for: common_enums::TransactionType::Payment, + let algo = match dynamic_routing_type { + routing_types::DynamicRoutingType::SuccessRateBasedRouting => { + let default_success_based_routing_config = + routing_types::SuccessBasedRoutingConfig::default(); + routing_algorithm::RoutingAlgorithm { + algorithm_id: algorithm_id.clone(), + profile_id: profile_id.clone(), + merchant_id, + name: SUCCESS_BASED_DYNAMIC_ROUTING_ALGORITHM.to_string(), + description: None, + kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic, + algorithm_data: serde_json::json!(default_success_based_routing_config), + created_at: timestamp, + modified_at: timestamp, + algorithm_for: common_enums::TransactionType::Payment, + } + } + routing_types::DynamicRoutingType::EliminationRouting => { + let default_elimination_routing_config = + routing_types::EliminationRoutingConfig::default(); + routing_algorithm::RoutingAlgorithm { + algorithm_id: algorithm_id.clone(), + profile_id: profile_id.clone(), + merchant_id, + name: ELIMINATION_BASED_DYNAMIC_ROUTING_ALGORITHM.to_string(), + description: None, + kind: diesel_models::enums::RoutingAlgorithmKind::Dynamic, + algorithm_data: serde_json::json!(default_elimination_routing_config), + created_at: timestamp, + modified_at: timestamp, + algorithm_for: common_enums::TransactionType::Payment, + } + } }; let record = db @@ -948,13 +1221,17 @@ pub async fn default_success_based_routing_setup( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Unable to insert record in routing algorithm table")?; - success_based_dynamic_routing_algo.update_algorithm_id(algorithm_id, feature_to_enable); + dynamic_routing_algo_ref.update_algorithm_id( + algorithm_id, + feature_to_enable, + dynamic_routing_type, + ); update_business_profile_active_dynamic_algorithm_ref( db, key_manager_state, &key_store, business_profile, - success_based_dynamic_routing_algo, + dynamic_routing_algo_ref, ) .await?; @@ -1001,35 +1278,35 @@ impl SuccessBasedRoutingConfigParamsInterpolator { pub fn get_string_val( &self, - params: &Vec, + params: &Vec, ) -> String { let mut parts: Vec = Vec::new(); for param in params { let val = match param { - routing_types::SuccessBasedRoutingConfigParams::PaymentMethod => self + routing_types::DynamicRoutingConfigParams::PaymentMethod => self .payment_method .as_ref() .map_or(String::new(), |pm| pm.to_string()), - routing_types::SuccessBasedRoutingConfigParams::PaymentMethodType => self + routing_types::DynamicRoutingConfigParams::PaymentMethodType => self .payment_method_type .as_ref() .map_or(String::new(), |pmt| pmt.to_string()), - routing_types::SuccessBasedRoutingConfigParams::AuthenticationType => self + routing_types::DynamicRoutingConfigParams::AuthenticationType => self .authentication_type .as_ref() .map_or(String::new(), |at| at.to_string()), - routing_types::SuccessBasedRoutingConfigParams::Currency => self + routing_types::DynamicRoutingConfigParams::Currency => self .currency .as_ref() .map_or(String::new(), |cur| cur.to_string()), - routing_types::SuccessBasedRoutingConfigParams::Country => self + routing_types::DynamicRoutingConfigParams::Country => self .country .as_ref() .map_or(String::new(), |cn| cn.to_string()), - routing_types::SuccessBasedRoutingConfigParams::CardNetwork => { + routing_types::DynamicRoutingConfigParams::CardNetwork => { self.card_network.clone().unwrap_or_default() } - routing_types::SuccessBasedRoutingConfigParams::CardBin => { + routing_types::DynamicRoutingConfigParams::CardBin => { self.card_bin.clone().unwrap_or_default() } }; diff --git a/crates/router/src/core/user.rs b/crates/router/src/core/user.rs index 1168ea87bf5c..4f77b2190444 100644 --- a/crates/router/src/core/user.rs +++ b/crates/router/src/core/user.rs @@ -44,6 +44,7 @@ use crate::{ pub mod dashboard_metadata; #[cfg(feature = "dummy_connector")] pub mod sample_data; +pub mod theme; #[cfg(feature = "email")] pub async fn signup_with_merchant_id( @@ -216,12 +217,12 @@ pub async fn connect_account( .await; logger::info!(?send_email_result); - return Ok(ApplicationResponse::Json( + Ok(ApplicationResponse::Json( user_api::ConnectAccountResponse { is_email_sent: send_email_result.is_ok(), user_id: user_from_db.get_user_id().to_string(), }, - )); + )) } else if find_user .as_ref() .map_err(|e| e.current_context().is_db_not_found()) @@ -1593,27 +1594,6 @@ pub async fn send_verification_mail( Ok(ApplicationResponse::StatusOk) } -#[cfg(feature = "recon")] -pub async fn verify_token( - state: SessionState, - user: auth::UserFromToken, -) -> UserResponse { - let user_in_db = user - .get_user_from_db(&state) - .await - .attach_printable_lazy(|| { - format!( - "Failed to fetch the user from DB for user_id - {}", - user.user_id - ) - })?; - - Ok(ApplicationResponse::Json(user_api::VerifyTokenResponse { - merchant_id: user.merchant_id.to_owned(), - user_email: user_in_db.0.email, - })) -} - pub async fn update_user_details( state: SessionState, user_token: auth::UserFromToken, diff --git a/crates/router/src/core/user/theme.rs b/crates/router/src/core/user/theme.rs new file mode 100644 index 000000000000..dbf11256a502 --- /dev/null +++ b/crates/router/src/core/user/theme.rs @@ -0,0 +1,225 @@ +use api_models::user::theme as theme_api; +use common_utils::{ + ext_traits::{ByteSliceExt, Encode}, + types::theme::ThemeLineage, +}; +use diesel_models::user::theme::ThemeNew; +use error_stack::ResultExt; +use hyperswitch_domain_models::api::ApplicationResponse; +use masking::ExposeInterface; +use rdkafka::message::ToBytes; +use uuid::Uuid; + +use crate::{ + core::errors::{StorageErrorExt, UserErrors, UserResponse}, + routes::SessionState, + utils::user::theme as theme_utils, +}; + +pub async fn get_theme_using_lineage( + state: SessionState, + lineage: ThemeLineage, +) -> UserResponse { + let theme = state + .global_store + .find_theme_by_lineage(lineage) + .await + .to_not_found_response(UserErrors::ThemeNotFound)?; + + let file = theme_utils::retrieve_file_from_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&theme.theme_id), + ) + .await?; + + let parsed_data = file + .to_bytes() + .parse_struct("ThemeData") + .change_context(UserErrors::InternalServerError)?; + + Ok(ApplicationResponse::Json(theme_api::GetThemeResponse { + theme_id: theme.theme_id, + theme_name: theme.theme_name, + entity_type: theme.entity_type, + tenant_id: theme.tenant_id, + org_id: theme.org_id, + merchant_id: theme.merchant_id, + profile_id: theme.profile_id, + theme_data: parsed_data, + })) +} + +pub async fn get_theme_using_theme_id( + state: SessionState, + theme_id: String, +) -> UserResponse { + let theme = state + .global_store + .find_theme_by_theme_id(theme_id.clone()) + .await + .to_not_found_response(UserErrors::ThemeNotFound)?; + + let file = theme_utils::retrieve_file_from_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&theme_id), + ) + .await?; + + let parsed_data = file + .to_bytes() + .parse_struct("ThemeData") + .change_context(UserErrors::InternalServerError)?; + + Ok(ApplicationResponse::Json(theme_api::GetThemeResponse { + theme_id: theme.theme_id, + theme_name: theme.theme_name, + entity_type: theme.entity_type, + tenant_id: theme.tenant_id, + org_id: theme.org_id, + merchant_id: theme.merchant_id, + profile_id: theme.profile_id, + theme_data: parsed_data, + })) +} + +pub async fn upload_file_to_theme_storage( + state: SessionState, + theme_id: String, + request: theme_api::UploadFileRequest, +) -> UserResponse<()> { + let db_theme = state + .global_store + .find_theme_by_lineage(request.lineage) + .await + .to_not_found_response(UserErrors::ThemeNotFound)?; + + if theme_id != db_theme.theme_id { + return Err(UserErrors::ThemeNotFound.into()); + } + + theme_utils::upload_file_to_theme_bucket( + &state, + &theme_utils::get_specific_file_key(&theme_id, &request.asset_name), + request.asset_data.expose(), + ) + .await?; + + Ok(ApplicationResponse::StatusOk) +} + +pub async fn create_theme( + state: SessionState, + request: theme_api::CreateThemeRequest, +) -> UserResponse { + theme_utils::validate_lineage(&state, &request.lineage).await?; + + let new_theme = ThemeNew::new( + Uuid::new_v4().to_string(), + request.theme_name, + request.lineage, + ); + + let db_theme = state + .global_store + .insert_theme(new_theme) + .await + .to_duplicate_response(UserErrors::ThemeAlreadyExists)?; + + theme_utils::upload_file_to_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&db_theme.theme_id), + request + .theme_data + .encode_to_vec() + .change_context(UserErrors::InternalServerError)?, + ) + .await?; + + let file = theme_utils::retrieve_file_from_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&db_theme.theme_id), + ) + .await?; + + let parsed_data = file + .to_bytes() + .parse_struct("ThemeData") + .change_context(UserErrors::InternalServerError)?; + + Ok(ApplicationResponse::Json(theme_api::GetThemeResponse { + theme_id: db_theme.theme_id, + entity_type: db_theme.entity_type, + tenant_id: db_theme.tenant_id, + org_id: db_theme.org_id, + merchant_id: db_theme.merchant_id, + profile_id: db_theme.profile_id, + theme_name: db_theme.theme_name, + theme_data: parsed_data, + })) +} + +pub async fn update_theme( + state: SessionState, + theme_id: String, + request: theme_api::UpdateThemeRequest, +) -> UserResponse { + let db_theme = state + .global_store + .find_theme_by_lineage(request.lineage) + .await + .to_not_found_response(UserErrors::ThemeNotFound)?; + + if theme_id != db_theme.theme_id { + return Err(UserErrors::ThemeNotFound.into()); + } + + theme_utils::upload_file_to_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&db_theme.theme_id), + request + .theme_data + .encode_to_vec() + .change_context(UserErrors::InternalServerError)?, + ) + .await?; + + let file = theme_utils::retrieve_file_from_theme_bucket( + &state, + &theme_utils::get_theme_file_key(&db_theme.theme_id), + ) + .await?; + + let parsed_data = file + .to_bytes() + .parse_struct("ThemeData") + .change_context(UserErrors::InternalServerError)?; + + Ok(ApplicationResponse::Json(theme_api::GetThemeResponse { + theme_id: db_theme.theme_id, + entity_type: db_theme.entity_type, + tenant_id: db_theme.tenant_id, + org_id: db_theme.org_id, + merchant_id: db_theme.merchant_id, + profile_id: db_theme.profile_id, + theme_name: db_theme.theme_name, + theme_data: parsed_data, + })) +} + +pub async fn delete_theme( + state: SessionState, + theme_id: String, + lineage: ThemeLineage, +) -> UserResponse<()> { + state + .global_store + .delete_theme_by_lineage_and_theme_id(theme_id.clone(), lineage) + .await + .to_not_found_response(UserErrors::ThemeNotFound)?; + + // TODO (#6717): Delete theme folder from the theme storage. + // Currently there is no simple or easy way to delete a whole folder from S3. + // So, we are not deleting the theme folder from the theme storage. + + Ok(ApplicationResponse::StatusOk) +} diff --git a/crates/router/src/core/user_role/role.rs b/crates/router/src/core/user_role/role.rs index 0250415d4fda..c01d585feb76 100644 --- a/crates/router/src/core/user_role/role.rs +++ b/crates/router/src/core/user_role/role.rs @@ -1,6 +1,6 @@ use std::collections::HashSet; -use api_models::user_role::role::{self as role_api}; +use api_models::user_role::role as role_api; use common_enums::{EntityType, ParentGroup, PermissionGroup, RoleScope}; use common_utils::generate_id_with_default_len; use diesel_models::role::{RoleNew, RoleUpdate}; diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 776692d6bec1..99f93f685dfc 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -108,7 +108,7 @@ pub async fn construct_payout_router_data<'a, F>( } }); - let address = PaymentAddress::new(None, billing_address, None, None); + let address = PaymentAddress::new(None, billing_address.map(From::from), None, None); let test_mode: Option = merchant_connector_account.is_test_mode_on(); let payouts = &payout_data.payouts; diff --git a/crates/router/src/core/webhooks/incoming_v2.rs b/crates/router/src/core/webhooks/incoming_v2.rs index c1734794fcc7..b91a6f0e9a01 100644 --- a/crates/router/src/core/webhooks/incoming_v2.rs +++ b/crates/router/src/core/webhooks/incoming_v2.rs @@ -614,12 +614,32 @@ where } api_models::payments::PaymentIdType::PreprocessingId(ref _id) => todo!(), }; + + // We need the address here to send it in the response + // In case we need to send an outgoing webhook, we might have to send the billing address and shipping address + let payment_address = hyperswitch_domain_models::payment_address::PaymentAddress::new( + payment_intent + .shipping_address + .clone() + .map(|address| address.into_inner()), + payment_intent + .billing_address + .clone() + .map(|address| address.into_inner()), + payment_attempt + .payment_method_billing_address + .clone() + .map(|address| address.into_inner()), + Some(true), + ); + Ok(payments::operations::GetTrackerResponse { payment_data: PaymentStatusData { flow: PhantomData, payment_intent, payment_attempt: Some(payment_attempt), should_sync_with_connector: true, + payment_address, }, }) } diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index ec45d9e18d70..9a284f1399d5 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -3723,6 +3723,13 @@ impl ThemeInterface for KafkaStore { self.diesel_store.insert_theme(theme).await } + async fn find_theme_by_theme_id( + &self, + theme_id: String, + ) -> CustomResult { + self.diesel_store.find_theme_by_theme_id(theme_id).await + } + async fn find_theme_by_lineage( &self, lineage: ThemeLineage, diff --git a/crates/router/src/db/user/theme.rs b/crates/router/src/db/user/theme.rs index f1e4f4f794eb..9b55a98d0ad3 100644 --- a/crates/router/src/db/user/theme.rs +++ b/crates/router/src/db/user/theme.rs @@ -16,6 +16,11 @@ pub trait ThemeInterface { theme: storage::ThemeNew, ) -> CustomResult; + async fn find_theme_by_theme_id( + &self, + theme_id: String, + ) -> CustomResult; + async fn find_theme_by_lineage( &self, lineage: ThemeLineage, @@ -41,6 +46,16 @@ impl ThemeInterface for Store { .map_err(|error| report!(errors::StorageError::from(error))) } + async fn find_theme_by_theme_id( + &self, + theme_id: String, + ) -> CustomResult { + let conn = connection::pg_connection_read(self).await?; + storage::Theme::find_by_theme_id(&conn, theme_id) + .await + .map_err(|error| report!(errors::StorageError::from(error))) + } + async fn find_theme_by_lineage( &self, lineage: ThemeLineage, @@ -165,6 +180,24 @@ impl ThemeInterface for MockDb { Ok(theme) } + async fn find_theme_by_theme_id( + &self, + theme_id: String, + ) -> CustomResult { + let themes = self.themes.lock().await; + themes + .iter() + .find(|theme| theme.theme_id == theme_id) + .cloned() + .ok_or( + errors::StorageError::ValueNotFound(format!( + "Theme with id {} not found", + theme_id + )) + .into(), + ) + } + async fn find_theme_by_lineage( &self, lineage: ThemeLineage, diff --git a/crates/router/src/db/user_authentication_method.rs b/crates/router/src/db/user_authentication_method.rs index bcc2313d5dbd..a02e7bdb11ff 100644 --- a/crates/router/src/db/user_authentication_method.rs +++ b/crates/router/src/db/user_authentication_method.rs @@ -1,4 +1,4 @@ -use diesel_models::user_authentication_method::{self as storage}; +use diesel_models::user_authentication_method as storage; use error_stack::report; use router_env::{instrument, tracing}; diff --git a/crates/router/src/events/audit_events.rs b/crates/router/src/events/audit_events.rs index 5f2ed10bc5f2..c314fa8409fa 100644 --- a/crates/router/src/events/audit_events.rs +++ b/crates/router/src/events/audit_events.rs @@ -33,6 +33,7 @@ pub enum AuditEventType { }, PaymentApprove, PaymentCreate, + PaymentCompleteAuthorize, PaymentReject { error_code: Option, error_message: Option, @@ -78,6 +79,7 @@ impl Event for AuditEvent { AuditEventType::PaymentUpdate { .. } => "payment_update", AuditEventType::PaymentApprove { .. } => "payment_approve", AuditEventType::PaymentCreate { .. } => "payment_create", + AuditEventType::PaymentCompleteAuthorize => "payment_complete_authorize", AuditEventType::PaymentReject { .. } => "payment_rejected", }; format!( diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index 1964c1cbfa5b..0fca984cc572 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -110,6 +110,7 @@ pub struct SessionState { #[cfg(feature = "olap")] pub opensearch_client: Arc, pub grpc_client: Arc, + pub theme_storage_client: Arc, } impl scheduler::SchedulerSessionState for SessionState { fn get_db(&self) -> Box { @@ -208,6 +209,7 @@ pub struct AppState { pub file_storage_client: Arc, pub encryption_client: Arc, pub grpc_client: Arc, + pub theme_storage_client: Arc, } impl scheduler::SchedulerAppState for AppState { fn get_tenants(&self) -> Vec { @@ -367,6 +369,7 @@ impl AppState { let email_client = Arc::new(create_email_client(&conf).await); let file_storage_client = conf.file_storage.get_file_storage_client().await; + let theme_storage_client = conf.theme_storage.get_file_storage_client().await; let grpc_client = conf.grpc_client.get_grpc_client_interface().await; @@ -387,6 +390,7 @@ impl AppState { file_storage_client, encryption_client, grpc_client, + theme_storage_client, } }) .await @@ -472,6 +476,7 @@ impl AppState { #[cfg(feature = "olap")] opensearch_client: Arc::clone(&self.opensearch_client), grpc_client: Arc::clone(&self.grpc_client), + theme_storage_client: self.theme_storage_client.clone(), }) } } @@ -1216,7 +1221,10 @@ impl Recon { .service( web::resource("/request").route(web::post().to(recon_routes::request_for_recon)), ) - .service(web::resource("/verify_token").route(web::get().to(user::verify_recon_token))) + .service( + web::resource("/verify_token") + .route(web::get().to(recon_routes::verify_recon_token)), + ) } } @@ -1755,9 +1763,9 @@ impl Profile { #[cfg(feature = "dynamic_routing")] { - route = - route.service( - web::scope("/{profile_id}/dynamic_routing").service( + route = route.service( + web::scope("/{profile_id}/dynamic_routing") + .service( web::scope("/success_based") .service( web::resource("/toggle") @@ -1770,8 +1778,14 @@ impl Profile { ) }), )), + ) + .service( + web::scope("/elimination").service( + web::resource("/toggle") + .route(web::post().to(routing::toggle_elimination_routing)), + ), ), - ); + ); } route = route.service( @@ -2121,6 +2135,23 @@ impl User { .route(web::delete().to(user::delete_sample_data)), ) } + + route = route.service( + web::scope("/theme") + .service( + web::resource("") + .route(web::get().to(user::theme::get_theme_using_lineage)) + .route(web::post().to(user::theme::create_theme)), + ) + .service( + web::resource("/{theme_id}") + .route(web::get().to(user::theme::get_theme_using_theme_id)) + .route(web::put().to(user::theme::update_theme)) + .route(web::post().to(user::theme::upload_file_to_theme_storage)) + .route(web::delete().to(user::theme::delete_theme)), + ), + ); + route } } diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs index 4d3718b967dd..1c7db127ffcc 100644 --- a/crates/router/src/routes/lock_utils.rs +++ b/crates/router/src/routes/lock_utils.rs @@ -259,7 +259,13 @@ impl From for ApiIdentifier { | Flow::ListMerchantsForUserInOrg | Flow::ListProfileForUserInOrgAndMerchant | Flow::ListInvitationsForUser - | Flow::AuthSelect => Self::User, + | Flow::AuthSelect + | Flow::GetThemeUsingLineage + | Flow::GetThemeUsingThemeId + | Flow::UploadFileToThemeStorage + | Flow::CreateTheme + | Flow::UpdateTheme + | Flow::DeleteTheme => Self::User, Flow::ListRolesV2 | Flow::ListInvitableRolesAtEntityLevel diff --git a/crates/router/src/routes/payment_link.rs b/crates/router/src/routes/payment_link.rs index 783566335bc8..71f10fe73e91 100644 --- a/crates/router/src/routes/payment_link.rs +++ b/crates/router/src/routes/payment_link.rs @@ -26,7 +26,6 @@ use crate::{ security(("api_key" = []), ("publishable_key" = [])) )] #[instrument(skip(state, req), fields(flow = ?Flow::PaymentLinkRetrieve))] - pub async fn payment_link_retrieve( state: web::Data, req: actix_web::HttpRequest, diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index 93f50f3ed9a2..27a5462c05ea 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -1977,7 +1977,7 @@ impl GetLockingInput for payment_types::PaymentsCaptureRequest { struct FPaymentsApproveRequest<'a>(&'a payment_types::PaymentsApproveRequest); #[cfg(feature = "oltp")] -impl<'a> GetLockingInput for FPaymentsApproveRequest<'a> { +impl GetLockingInput for FPaymentsApproveRequest<'_> { fn get_locking_input(&self, flow: F) -> api_locking::LockAction where F: types::FlowMetric, @@ -1997,7 +1997,7 @@ impl<'a> GetLockingInput for FPaymentsApproveRequest<'a> { struct FPaymentsRejectRequest<'a>(&'a payment_types::PaymentsRejectRequest); #[cfg(feature = "oltp")] -impl<'a> GetLockingInput for FPaymentsRejectRequest<'a> { +impl GetLockingInput for FPaymentsRejectRequest<'_> { fn get_locking_input(&self, flow: F) -> api_locking::LockAction where F: types::FlowMetric, diff --git a/crates/router/src/routes/recon.rs b/crates/router/src/routes/recon.rs index cdc2ae758e92..cfd076c7100c 100644 --- a/crates/router/src/routes/recon.rs +++ b/crates/router/src/routes/recon.rs @@ -38,7 +38,7 @@ pub async fn request_for_recon(state: web::Data, http_req: HttpRequest (), |state, user, _, _| recon::send_recon_request(state, user), &authentication::JWTAuth { - permission: Permission::MerchantReconWrite, + permission: Permission::MerchantAccountWrite, }, api_locking::LockAction::NotApplicable, )) @@ -54,7 +54,24 @@ pub async fn get_recon_token(state: web::Data, req: HttpRequest) -> Ht (), |state, user, _, _| recon::generate_recon_token(state, user), &authentication::JWTAuth { - permission: Permission::MerchantReconWrite, + permission: Permission::MerchantReconTokenRead, + }, + api_locking::LockAction::NotApplicable, + )) + .await +} + +#[cfg(feature = "recon")] +pub async fn verify_recon_token(state: web::Data, http_req: HttpRequest) -> HttpResponse { + let flow = Flow::ReconVerifyToken; + Box::pin(api::server_wrap( + flow, + state.clone(), + &http_req, + (), + |state, user, _req, _| recon::verify_recon_token(state, user), + &authentication::JWTAuth { + permission: Permission::MerchantReconTokenRead, }, api_locking::LockAction::NotApplicable, )) diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs index cb7744f52009..d22c5e974906 100644 --- a/crates/router/src/routes/routing.rs +++ b/crates/router/src/routes/routing.rs @@ -1014,11 +1014,11 @@ pub async fn routing_update_default_config_for_profile( pub async fn toggle_success_based_routing( state: web::Data, req: HttpRequest, - query: web::Query, - path: web::Path, + query: web::Query, + path: web::Path, ) -> impl Responder { let flow = Flow::ToggleDynamicRouting; - let wrapper = routing_types::ToggleSuccessBasedRoutingWrapper { + let wrapper = routing_types::ToggleDynamicRoutingWrapper { feature_to_enable: query.into_inner().enable, profile_id: path.into_inner().profile_id, }; @@ -1029,14 +1029,15 @@ pub async fn toggle_success_based_routing( wrapper.clone(), |state, auth: auth::AuthenticationData, - wrapper: routing_types::ToggleSuccessBasedRoutingWrapper, + wrapper: routing_types::ToggleDynamicRoutingWrapper, _| { - routing::toggle_success_based_routing( + routing::toggle_specific_dynamic_routing( state, auth.merchant_account, auth.key_store, wrapper.feature_to_enable, wrapper.profile_id, + api_models::routing::DynamicRoutingType::SuccessRateBasedRouting, ) }, auth::auth_type( @@ -1085,3 +1086,46 @@ pub async fn success_based_routing_update_configs( )) .await } +#[cfg(all(feature = "olap", feature = "v1", feature = "dynamic_routing"))] +#[instrument(skip_all)] +pub async fn toggle_elimination_routing( + state: web::Data, + req: HttpRequest, + query: web::Query, + path: web::Path, +) -> impl Responder { + let flow = Flow::ToggleDynamicRouting; + let wrapper = routing_types::ToggleDynamicRoutingWrapper { + feature_to_enable: query.into_inner().enable, + profile_id: path.into_inner().profile_id, + }; + Box::pin(oss_api::server_wrap( + flow, + state, + &req, + wrapper.clone(), + |state, + auth: auth::AuthenticationData, + wrapper: routing_types::ToggleDynamicRoutingWrapper, + _| { + routing::toggle_specific_dynamic_routing( + state, + auth.merchant_account, + auth.key_store, + wrapper.feature_to_enable, + wrapper.profile_id, + api_models::routing::DynamicRoutingType::EliminationRouting, + ) + }, + auth::auth_type( + &auth::HeaderAuth(auth::ApiKeyAuth), + &auth::JWTAuthProfileFromRoute { + profile_id: wrapper.profile_id, + required_permission: Permission::ProfileRoutingWrite, + }, + req.headers(), + ), + api_locking::LockAction::NotApplicable, + )) + .await +} diff --git a/crates/router/src/routes/user.rs b/crates/router/src/routes/user.rs index 8fc0dad452a9..d5f31be39659 100644 --- a/crates/router/src/routes/user.rs +++ b/crates/router/src/routes/user.rs @@ -1,3 +1,5 @@ +pub mod theme; + use actix_web::{web, HttpRequest, HttpResponse}; #[cfg(feature = "dummy_connector")] use api_models::user::sample_data::SampleDataRequest; @@ -487,23 +489,6 @@ pub async fn verify_email_request( .await } -#[cfg(feature = "recon")] -pub async fn verify_recon_token(state: web::Data, http_req: HttpRequest) -> HttpResponse { - let flow = Flow::ReconVerifyToken; - Box::pin(api::server_wrap( - flow, - state.clone(), - &http_req, - (), - |state, user, _req, _| user_core::verify_token(state, user), - &auth::JWTAuth { - permission: Permission::MerchantReconWrite, - }, - api_locking::LockAction::NotApplicable, - )) - .await -} - pub async fn update_user_account_details( state: web::Data, req: HttpRequest, diff --git a/crates/router/src/routes/user/theme.rs b/crates/router/src/routes/user/theme.rs new file mode 100644 index 000000000000..69a8e9a5378f --- /dev/null +++ b/crates/router/src/routes/user/theme.rs @@ -0,0 +1,145 @@ +use actix_multipart::form::MultipartForm; +use actix_web::{web, HttpRequest, HttpResponse}; +use api_models::user::theme as theme_api; +use common_utils::types::theme::ThemeLineage; +use masking::Secret; +use router_env::Flow; + +use crate::{ + core::{api_locking, user::theme as theme_core}, + routes::AppState, + services::{api, authentication as auth}, +}; + +pub async fn get_theme_using_lineage( + state: web::Data, + req: HttpRequest, + query: web::Query, +) -> HttpResponse { + let flow = Flow::GetThemeUsingLineage; + let lineage = query.into_inner(); + + Box::pin(api::server_wrap( + flow, + state, + &req, + lineage, + |state, _, lineage, _| theme_core::get_theme_using_lineage(state, lineage), + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} + +pub async fn get_theme_using_theme_id( + state: web::Data, + req: HttpRequest, + path: web::Path, +) -> HttpResponse { + let flow = Flow::GetThemeUsingThemeId; + let payload = path.into_inner(); + + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, _, payload, _| theme_core::get_theme_using_theme_id(state, payload), + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} + +pub async fn upload_file_to_theme_storage( + state: web::Data, + req: HttpRequest, + path: web::Path, + MultipartForm(payload): MultipartForm, + query: web::Query, +) -> HttpResponse { + let flow = Flow::UploadFileToThemeStorage; + let theme_id = path.into_inner(); + let payload = theme_api::UploadFileRequest { + lineage: query.into_inner(), + asset_name: payload.asset_name.into_inner(), + asset_data: Secret::new(payload.asset_data.data.to_vec()), + }; + + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, _, payload, _| { + theme_core::upload_file_to_theme_storage(state, theme_id.clone(), payload) + }, + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} + +pub async fn create_theme( + state: web::Data, + req: HttpRequest, + payload: web::Json, +) -> HttpResponse { + let flow = Flow::CreateTheme; + let payload = payload.into_inner(); + + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, _, payload, _| theme_core::create_theme(state, payload), + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} + +pub async fn update_theme( + state: web::Data, + req: HttpRequest, + path: web::Path, + payload: web::Json, +) -> HttpResponse { + let flow = Flow::UpdateTheme; + let theme_id = path.into_inner(); + let payload = payload.into_inner(); + + Box::pin(api::server_wrap( + flow, + state, + &req, + payload, + |state, _, payload, _| theme_core::update_theme(state, theme_id.clone(), payload), + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} + +pub async fn delete_theme( + state: web::Data, + req: HttpRequest, + path: web::Path, + query: web::Query, +) -> HttpResponse { + let flow = Flow::DeleteTheme; + let theme_id = path.into_inner(); + let lineage = query.into_inner(); + + Box::pin(api::server_wrap( + flow, + state, + &req, + lineage, + |state, _, lineage, _| theme_core::delete_theme(state, theme_id.clone(), lineage), + &auth::AdminApiAuth, + api_locking::LockAction::NotApplicable, + )) + .await +} diff --git a/crates/router/src/services/api/client.rs b/crates/router/src/services/api/client.rs index e1f113633a82..9a496c18d9a6 100644 --- a/crates/router/src/services/api/client.rs +++ b/crates/router/src/services/api/client.rs @@ -403,9 +403,7 @@ impl ApiClient for ProxyClient { fn add_flow_name(&mut self, _flow_name: String) {} } -/// /// Api client for testing sending request -/// #[derive(Clone)] pub struct MockApiClient; diff --git a/crates/router/src/services/authentication.rs b/crates/router/src/services/authentication.rs index 1967eafd180c..58253684a278 100644 --- a/crates/router/src/services/authentication.rs +++ b/crates/router/src/services/authentication.rs @@ -90,6 +90,12 @@ pub struct AuthenticationDataWithUser { pub profile_id: id_type::ProfileId, } +#[derive(Clone)] +pub struct UserFromTokenWithRoleInfo { + pub user: UserFromToken, + pub role_info: authorization::roles::RoleInfo, +} + #[derive(Clone, Debug, Eq, PartialEq, Serialize)] #[serde( tag = "api_auth_type", @@ -3228,3 +3234,91 @@ where Ok((auth, auth_type)) } } + +#[cfg(feature = "recon")] +#[async_trait] +impl AuthenticateAndFetch for JWTAuth +where + A: SessionStateInfo + Sync, +{ + async fn authenticate_and_fetch( + &self, + request_headers: &HeaderMap, + state: &A, + ) -> RouterResult<(UserFromTokenWithRoleInfo, AuthenticationType)> { + let payload = parse_jwt_payload::(request_headers, state).await?; + if payload.check_in_blacklist(state).await? { + return Err(errors::ApiErrorResponse::InvalidJwtToken.into()); + } + authorization::check_tenant( + payload.tenant_id.clone(), + &state.session_state().tenant.tenant_id, + )?; + let role_info = authorization::get_role_info(state, &payload).await?; + authorization::check_permission(&self.permission, &role_info)?; + + let user = UserFromToken { + user_id: payload.user_id.clone(), + merchant_id: payload.merchant_id.clone(), + org_id: payload.org_id, + role_id: payload.role_id, + profile_id: payload.profile_id, + tenant_id: payload.tenant_id, + }; + + Ok(( + UserFromTokenWithRoleInfo { user, role_info }, + AuthenticationType::MerchantJwt { + merchant_id: payload.merchant_id, + user_id: Some(payload.user_id), + }, + )) + } +} + +#[cfg(feature = "recon")] +#[derive(serde::Serialize, serde::Deserialize)] +pub struct ReconToken { + pub user_id: String, + pub merchant_id: id_type::MerchantId, + pub role_id: String, + pub exp: u64, + pub org_id: id_type::OrganizationId, + pub profile_id: id_type::ProfileId, + pub tenant_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub acl: Option, +} + +#[cfg(all(feature = "olap", feature = "recon"))] +impl ReconToken { + pub async fn new_token( + user_id: String, + merchant_id: id_type::MerchantId, + settings: &Settings, + org_id: id_type::OrganizationId, + profile_id: id_type::ProfileId, + tenant_id: Option, + role_info: authorization::roles::RoleInfo, + ) -> UserResult { + let exp_duration = std::time::Duration::from_secs(consts::JWT_TOKEN_TIME_IN_SECS); + let exp = jwt::generate_exp(exp_duration)?.as_secs(); + let acl = role_info.get_recon_acl(); + let optional_acl_str = serde_json::to_string(&acl) + .inspect_err(|err| logger::error!("Failed to serialize acl to string: {}", err)) + .change_context(errors::UserErrors::InternalServerError) + .attach_printable("Failed to serialize acl to string. Using empty ACL") + .ok(); + let token_payload = Self { + user_id, + merchant_id, + role_id: role_info.get_role_id().to_string(), + exp, + org_id, + profile_id, + tenant_id, + acl: optional_acl_str, + }; + jwt::generate_jwt(&token_payload, settings).await + } +} diff --git a/crates/router/src/services/authentication/decision.rs b/crates/router/src/services/authentication/decision.rs index c31a4696bc90..4ff9f8401baa 100644 --- a/crates/router/src/services/authentication/decision.rs +++ b/crates/router/src/services/authentication/decision.rs @@ -179,10 +179,7 @@ pub async fn revoke_api_key( call_decision_service(state, decision_config, rule, RULE_DELETE_METHOD).await } -/// -/// /// Safety: i64::MAX < u64::MAX -/// #[allow(clippy::as_conversions)] pub fn convert_expiry(expiry: time::PrimitiveDateTime) -> u64 { let now = common_utils::date_time::now(); diff --git a/crates/router/src/services/authorization/info.rs b/crates/router/src/services/authorization/info.rs index bd987e2fe9ae..2d808a4377ae 100644 --- a/crates/router/src/services/authorization/info.rs +++ b/crates/router/src/services/authorization/info.rs @@ -40,7 +40,10 @@ fn get_group_description(group: PermissionGroup) -> &'static str { PermissionGroup::MerchantDetailsView | PermissionGroup::AccountView => "View Merchant Details", PermissionGroup::MerchantDetailsManage | PermissionGroup::AccountManage => "Create, modify and delete Merchant Details like api keys, webhooks, etc", PermissionGroup::OrganizationManage => "Manage organization level tasks like create new Merchant accounts, Organization level roles, etc", - PermissionGroup::ReconOps => "View and manage reconciliation reports", + PermissionGroup::ReconReportsView => "View and access reconciliation reports and analytics", + PermissionGroup::ReconReportsManage => "Manage reconciliation reports", + PermissionGroup::ReconOpsView => "View and access reconciliation operations", + PermissionGroup::ReconOpsManage => "Manage reconciliation operations", } } @@ -52,6 +55,7 @@ pub fn get_parent_group_description(group: ParentGroup) -> &'static str { ParentGroup::Analytics => "View Analytics", ParentGroup::Users => "Manage and invite Users to the Team", ParentGroup::Account => "Create, modify and delete Merchant Details like api keys, webhooks, etc", - ParentGroup::Recon => "View and manage reconciliation reports", + ParentGroup::ReconOps => "View, manage reconciliation operations like upload and process files, run reconciliation etc", + ParentGroup::ReconReports => "View, manage reconciliation reports and analytics", } } diff --git a/crates/router/src/services/authorization/permission_groups.rs b/crates/router/src/services/authorization/permission_groups.rs index 57c385565a86..7ca8442c1cef 100644 --- a/crates/router/src/services/authorization/permission_groups.rs +++ b/crates/router/src/services/authorization/permission_groups.rs @@ -21,7 +21,9 @@ impl PermissionGroupExt for PermissionGroup { | Self::AnalyticsView | Self::UsersView | Self::MerchantDetailsView - | Self::AccountView => PermissionScope::Read, + | Self::AccountView + | Self::ReconOpsView + | Self::ReconReportsView => PermissionScope::Read, Self::OperationsManage | Self::ConnectorsManage @@ -29,8 +31,9 @@ impl PermissionGroupExt for PermissionGroup { | Self::UsersManage | Self::MerchantDetailsManage | Self::OrganizationManage - | Self::ReconOps - | Self::AccountManage => PermissionScope::Write, + | Self::AccountManage + | Self::ReconOpsManage + | Self::ReconReportsManage => PermissionScope::Write, } } @@ -41,12 +44,13 @@ impl PermissionGroupExt for PermissionGroup { Self::WorkflowsView | Self::WorkflowsManage => ParentGroup::Workflows, Self::AnalyticsView => ParentGroup::Analytics, Self::UsersView | Self::UsersManage => ParentGroup::Users, - Self::ReconOps => ParentGroup::Recon, Self::MerchantDetailsView | Self::OrganizationManage | Self::MerchantDetailsManage | Self::AccountView | Self::AccountManage => ParentGroup::Account, + Self::ReconOpsView | Self::ReconOpsManage => ParentGroup::ReconOps, + Self::ReconReportsView | Self::ReconReportsManage => ParentGroup::ReconReports, } } @@ -76,7 +80,11 @@ impl PermissionGroupExt for PermissionGroup { vec![Self::UsersView, Self::UsersManage] } - Self::ReconOps => vec![Self::ReconOps], + Self::ReconOpsView => vec![Self::ReconOpsView], + Self::ReconOpsManage => vec![Self::ReconOpsView, Self::ReconOpsManage], + + Self::ReconReportsView => vec![Self::ReconReportsView], + Self::ReconReportsManage => vec![Self::ReconReportsView, Self::ReconReportsManage], Self::MerchantDetailsView => vec![Self::MerchantDetailsView], Self::MerchantDetailsManage => { @@ -108,7 +116,8 @@ impl ParentGroupExt for ParentGroup { Self::Analytics => ANALYTICS.to_vec(), Self::Users => USERS.to_vec(), Self::Account => ACCOUNT.to_vec(), - Self::Recon => RECON.to_vec(), + Self::ReconOps => RECON_OPS.to_vec(), + Self::ReconReports => RECON_REPORTS.to_vec(), } } @@ -167,4 +176,18 @@ pub static USERS: [Resource; 2] = [Resource::User, Resource::Account]; pub static ACCOUNT: [Resource; 3] = [Resource::Account, Resource::ApiKey, Resource::WebhookEvent]; -pub static RECON: [Resource; 1] = [Resource::Recon]; +pub static RECON_OPS: [Resource; 7] = [ + Resource::ReconToken, + Resource::ReconFiles, + Resource::ReconUpload, + Resource::RunRecon, + Resource::ReconConfig, + Resource::ReconAndSettlementAnalytics, + Resource::ReconReports, +]; + +pub static RECON_REPORTS: [Resource; 3] = [ + Resource::ReconToken, + Resource::ReconAndSettlementAnalytics, + Resource::ReconReports, +]; diff --git a/crates/router/src/services/authorization/permissions.rs b/crates/router/src/services/authorization/permissions.rs index 6e472d55623b..6f6120074255 100644 --- a/crates/router/src/services/authorization/permissions.rs +++ b/crates/router/src/services/authorization/permissions.rs @@ -67,8 +67,32 @@ generate_permissions! { scopes: [Read, Write], entities: [Merchant] }, - Recon: { - scopes: [Write], + ReconToken: { + scopes: [Read], + entities: [Merchant] + }, + ReconFiles: { + scopes: [Read, Write], + entities: [Merchant] + }, + ReconAndSettlementAnalytics: { + scopes: [Read], + entities: [Merchant] + }, + ReconUpload: { + scopes: [Read, Write], + entities: [Merchant] + }, + ReconReports: { + scopes: [Read, Write], + entities: [Merchant] + }, + RunRecon: { + scopes: [Read, Write], + entities: [Merchant] + }, + ReconConfig: { + scopes: [Read, Write], entities: [Merchant] }, ] @@ -91,7 +115,13 @@ pub fn get_resource_name(resource: &Resource, entity_type: &EntityType) -> &'sta (Resource::Report, _) => "Operation Reports", (Resource::User, _) => "Users", (Resource::WebhookEvent, _) => "Webhook Events", - (Resource::Recon, _) => "Reconciliation Reports", + (Resource::ReconUpload, _) => "Reconciliation File Upload", + (Resource::RunRecon, _) => "Run Reconciliation Process", + (Resource::ReconConfig, _) => "Reconciliation Configurations", + (Resource::ReconToken, _) => "Generate & Verify Reconciliation Token", + (Resource::ReconFiles, _) => "Reconciliation Process Manager", + (Resource::ReconReports, _) => "Reconciliation Reports", + (Resource::ReconAndSettlementAnalytics, _) => "Reconciliation Analytics", (Resource::Account, EntityType::Profile) => "Business Profile Account", (Resource::Account, EntityType::Merchant) => "Merchant Account", (Resource::Account, EntityType::Organization) => "Organization Account", diff --git a/crates/router/src/services/authorization/roles.rs b/crates/router/src/services/authorization/roles.rs index bf66eb924669..f6c4f4b9ef29 100644 --- a/crates/router/src/services/authorization/roles.rs +++ b/crates/router/src/services/authorization/roles.rs @@ -1,8 +1,14 @@ +#[cfg(feature = "recon")] +use std::collections::HashMap; use std::collections::HashSet; +#[cfg(feature = "recon")] +use api_models::enums::ReconPermissionScope; use common_enums::{EntityType, PermissionGroup, Resource, RoleScope}; use common_utils::{errors::CustomResult, id_type}; +#[cfg(feature = "recon")] +use super::permission_groups::{RECON_OPS, RECON_REPORTS}; use super::{permission_groups::PermissionGroupExt, permissions::Permission}; use crate::{core::errors, routes::SessionState}; @@ -78,6 +84,38 @@ impl RoleInfo { }) } + #[cfg(feature = "recon")] + pub fn get_recon_acl(&self) -> HashMap { + let mut acl: HashMap = HashMap::new(); + let mut recon_resources = RECON_OPS.to_vec(); + recon_resources.extend(RECON_REPORTS); + let recon_internal_resources = [Resource::ReconToken]; + self.get_permission_groups() + .iter() + .for_each(|permission_group| { + permission_group.resources().iter().for_each(|resource| { + if recon_resources.contains(resource) + && !recon_internal_resources.contains(resource) + { + let scope = match resource { + Resource::ReconAndSettlementAnalytics => ReconPermissionScope::Read, + _ => ReconPermissionScope::from(permission_group.scope()), + }; + acl.entry(*resource) + .and_modify(|curr_scope| { + *curr_scope = if (*curr_scope) < scope { + scope + } else { + *curr_scope + } + }) + .or_insert(scope); + } + }) + }); + acl + } + pub async fn from_role_id_in_merchant_scope( state: &SessionState, role_id: &str, diff --git a/crates/router/src/services/authorization/roles/predefined_roles.rs b/crates/router/src/services/authorization/roles/predefined_roles.rs index 39f6d47f824b..9c67c12f5277 100644 --- a/crates/router/src/services/authorization/roles/predefined_roles.rs +++ b/crates/router/src/services/authorization/roles/predefined_roles.rs @@ -28,7 +28,10 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::MerchantDetailsManage, PermissionGroup::AccountManage, PermissionGroup::OrganizationManage, - PermissionGroup::ReconOps, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconOpsManage, + PermissionGroup::ReconReportsView, + PermissionGroup::ReconReportsManage, ], role_id: common_utils::consts::ROLE_ID_INTERNAL_ADMIN.to_string(), role_name: "internal_admin".to_string(), @@ -51,6 +54,8 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::UsersView, PermissionGroup::MerchantDetailsView, PermissionGroup::AccountView, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconReportsView, ], role_id: common_utils::consts::ROLE_ID_INTERNAL_VIEW_ONLY_USER.to_string(), role_name: "internal_view_only".to_string(), @@ -82,7 +87,10 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::MerchantDetailsManage, PermissionGroup::AccountManage, PermissionGroup::OrganizationManage, - PermissionGroup::ReconOps, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconOpsManage, + PermissionGroup::ReconReportsView, + PermissionGroup::ReconReportsManage, ], role_id: common_utils::consts::ROLE_ID_ORGANIZATION_ADMIN.to_string(), role_name: "organization_admin".to_string(), @@ -113,7 +121,10 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::AccountView, PermissionGroup::MerchantDetailsManage, PermissionGroup::AccountManage, - PermissionGroup::ReconOps, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconOpsManage, + PermissionGroup::ReconReportsView, + PermissionGroup::ReconReportsManage, ], role_id: consts::user_role::ROLE_ID_MERCHANT_ADMIN.to_string(), role_name: "merchant_admin".to_string(), @@ -136,6 +147,8 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::UsersView, PermissionGroup::MerchantDetailsView, PermissionGroup::AccountView, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconReportsView, ], role_id: consts::user_role::ROLE_ID_MERCHANT_VIEW_ONLY.to_string(), role_name: "merchant_view_only".to_string(), @@ -180,6 +193,8 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::AccountView, PermissionGroup::MerchantDetailsManage, PermissionGroup::AccountManage, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconReportsView, ], role_id: consts::user_role::ROLE_ID_MERCHANT_DEVELOPER.to_string(), role_name: "merchant_developer".to_string(), @@ -203,6 +218,9 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::UsersView, PermissionGroup::MerchantDetailsView, PermissionGroup::AccountView, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconOpsManage, + PermissionGroup::ReconReportsView, ], role_id: consts::user_role::ROLE_ID_MERCHANT_OPERATOR.to_string(), role_name: "merchant_operator".to_string(), @@ -223,6 +241,8 @@ pub static PREDEFINED_ROLES: Lazy> = Lazy::new(| PermissionGroup::UsersView, PermissionGroup::MerchantDetailsView, PermissionGroup::AccountView, + PermissionGroup::ReconOpsView, + PermissionGroup::ReconReportsView, ], role_id: consts::user_role::ROLE_ID_MERCHANT_CUSTOMER_SUPPORT.to_string(), role_name: "customer_support".to_string(), diff --git a/crates/router/src/services/email/types.rs b/crates/router/src/services/email/types.rs index 8c966d79d80c..66e730f08246 100644 --- a/crates/router/src/services/email/types.rs +++ b/crates/router/src/services/email/types.rs @@ -383,7 +383,6 @@ impl EmailData for InviteUser { pub struct ReconActivation { pub recipient_email: domain::UserEmail, pub user_name: domain::UserName, - pub settings: std::sync::Arc, pub subject: &'static str, } @@ -458,7 +457,6 @@ pub struct ProFeatureRequest { pub merchant_id: common_utils::id_type::MerchantId, pub user_name: domain::UserName, pub user_email: domain::UserEmail, - pub settings: std::sync::Arc, pub subject: String, } diff --git a/crates/router/src/services/kafka.rs b/crates/router/src/services/kafka.rs index 51ae9456ecc9..91968510a6b6 100644 --- a/crates/router/src/services/kafka.rs +++ b/crates/router/src/services/kafka.rs @@ -94,7 +94,7 @@ impl<'a, T: KafkaMessage> KafkaEvent<'a, T> { } } -impl<'a, T: KafkaMessage> KafkaMessage for KafkaEvent<'a, T> { +impl KafkaMessage for KafkaEvent<'_, T> { fn key(&self) -> String { self.event.key() } @@ -130,7 +130,7 @@ impl<'a, T: KafkaMessage> KafkaConsolidatedEvent<'a, T> { } } -impl<'a, T: KafkaMessage> KafkaMessage for KafkaConsolidatedEvent<'a, T> { +impl KafkaMessage for KafkaConsolidatedEvent<'_, T> { fn key(&self) -> String { self.log.event.key() } diff --git a/crates/router/src/services/kafka/authentication.rs b/crates/router/src/services/kafka/authentication.rs index 67e488d6c8fb..5cf2d066ee2e 100644 --- a/crates/router/src/services/kafka/authentication.rs +++ b/crates/router/src/services/kafka/authentication.rs @@ -86,7 +86,7 @@ impl<'a> KafkaAuthentication<'a> { } } -impl<'a> super::KafkaMessage for KafkaAuthentication<'a> { +impl super::KafkaMessage for KafkaAuthentication<'_> { fn key(&self) -> String { format!( "{}_{}", diff --git a/crates/router/src/services/kafka/authentication_event.rs b/crates/router/src/services/kafka/authentication_event.rs index 7c8b77a38486..4169ff7b42a2 100644 --- a/crates/router/src/services/kafka/authentication_event.rs +++ b/crates/router/src/services/kafka/authentication_event.rs @@ -87,7 +87,7 @@ impl<'a> KafkaAuthenticationEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaAuthenticationEvent<'a> { +impl super::KafkaMessage for KafkaAuthenticationEvent<'_> { fn key(&self) -> String { format!( "{}_{}", diff --git a/crates/router/src/services/kafka/dispute.rs b/crates/router/src/services/kafka/dispute.rs index cc3a538851ef..4414af494f2f 100644 --- a/crates/router/src/services/kafka/dispute.rs +++ b/crates/router/src/services/kafka/dispute.rs @@ -71,7 +71,7 @@ impl<'a> KafkaDispute<'a> { } } -impl<'a> super::KafkaMessage for KafkaDispute<'a> { +impl super::KafkaMessage for KafkaDispute<'_> { fn key(&self) -> String { format!( "{}_{}_{}", diff --git a/crates/router/src/services/kafka/dispute_event.rs b/crates/router/src/services/kafka/dispute_event.rs index 64d91e8acaa6..92327c044d74 100644 --- a/crates/router/src/services/kafka/dispute_event.rs +++ b/crates/router/src/services/kafka/dispute_event.rs @@ -72,7 +72,7 @@ impl<'a> KafkaDisputeEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaDisputeEvent<'a> { +impl super::KafkaMessage for KafkaDisputeEvent<'_> { fn key(&self) -> String { format!( "{}_{}_{}", diff --git a/crates/router/src/services/kafka/fraud_check.rs b/crates/router/src/services/kafka/fraud_check.rs index 26fa9e6b4e26..3010f85753b9 100644 --- a/crates/router/src/services/kafka/fraud_check.rs +++ b/crates/router/src/services/kafka/fraud_check.rs @@ -53,7 +53,7 @@ impl<'a> KafkaFraudCheck<'a> { } } -impl<'a> super::KafkaMessage for KafkaFraudCheck<'a> { +impl super::KafkaMessage for KafkaFraudCheck<'_> { fn key(&self) -> String { format!( "{}_{}_{}_{}", diff --git a/crates/router/src/services/kafka/fraud_check_event.rs b/crates/router/src/services/kafka/fraud_check_event.rs index f35748cb1c8c..4fd711744188 100644 --- a/crates/router/src/services/kafka/fraud_check_event.rs +++ b/crates/router/src/services/kafka/fraud_check_event.rs @@ -52,7 +52,7 @@ impl<'a> KafkaFraudCheckEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaFraudCheckEvent<'a> { +impl super::KafkaMessage for KafkaFraudCheckEvent<'_> { fn key(&self) -> String { format!( "{}_{}_{}_{}", diff --git a/crates/router/src/services/kafka/payment_attempt.rs b/crates/router/src/services/kafka/payment_attempt.rs index e585b21d4b2b..adfff7450bc0 100644 --- a/crates/router/src/services/kafka/payment_attempt.rs +++ b/crates/router/src/services/kafka/payment_attempt.rs @@ -180,7 +180,7 @@ impl<'a> KafkaPaymentAttempt<'a> { } } -impl<'a> super::KafkaMessage for KafkaPaymentAttempt<'a> { +impl super::KafkaMessage for KafkaPaymentAttempt<'_> { fn key(&self) -> String { format!( "{}_{}_{}", diff --git a/crates/router/src/services/kafka/payment_attempt_event.rs b/crates/router/src/services/kafka/payment_attempt_event.rs index cbce46ad9c75..177b211ae897 100644 --- a/crates/router/src/services/kafka/payment_attempt_event.rs +++ b/crates/router/src/services/kafka/payment_attempt_event.rs @@ -181,7 +181,7 @@ impl<'a> KafkaPaymentAttemptEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaPaymentAttemptEvent<'a> { +impl super::KafkaMessage for KafkaPaymentAttemptEvent<'_> { fn key(&self) -> String { format!( "{}_{}_{}", diff --git a/crates/router/src/services/kafka/payment_intent.rs b/crates/router/src/services/kafka/payment_intent.rs index 82e33de8c609..378bddf193ba 100644 --- a/crates/router/src/services/kafka/payment_intent.rs +++ b/crates/router/src/services/kafka/payment_intent.rs @@ -180,7 +180,7 @@ impl KafkaPaymentIntent<'_> { } } -impl<'a> super::KafkaMessage for KafkaPaymentIntent<'a> { +impl super::KafkaMessage for KafkaPaymentIntent<'_> { fn key(&self) -> String { format!( "{}_{}", diff --git a/crates/router/src/services/kafka/payment_intent_event.rs b/crates/router/src/services/kafka/payment_intent_event.rs index 5657846ca4c7..7509f7116206 100644 --- a/crates/router/src/services/kafka/payment_intent_event.rs +++ b/crates/router/src/services/kafka/payment_intent_event.rs @@ -182,7 +182,7 @@ impl<'a> KafkaPaymentIntentEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaPaymentIntentEvent<'a> { +impl super::KafkaMessage for KafkaPaymentIntentEvent<'_> { fn key(&self) -> String { format!( "{}_{}", diff --git a/crates/router/src/services/kafka/payout.rs b/crates/router/src/services/kafka/payout.rs index 7a6254bd527d..babf7c1c5682 100644 --- a/crates/router/src/services/kafka/payout.rs +++ b/crates/router/src/services/kafka/payout.rs @@ -77,7 +77,7 @@ impl<'a> KafkaPayout<'a> { } } -impl<'a> super::KafkaMessage for KafkaPayout<'a> { +impl super::KafkaMessage for KafkaPayout<'_> { fn key(&self) -> String { format!( "{}_{}", diff --git a/crates/router/src/services/kafka/refund.rs b/crates/router/src/services/kafka/refund.rs index 7eff6f881baf..a7e37930cf2a 100644 --- a/crates/router/src/services/kafka/refund.rs +++ b/crates/router/src/services/kafka/refund.rs @@ -66,7 +66,7 @@ impl<'a> KafkaRefund<'a> { } } -impl<'a> super::KafkaMessage for KafkaRefund<'a> { +impl super::KafkaMessage for KafkaRefund<'_> { fn key(&self) -> String { format!( "{}_{}_{}_{}", diff --git a/crates/router/src/services/kafka/refund_event.rs b/crates/router/src/services/kafka/refund_event.rs index 8f9f77878a10..74278944b041 100644 --- a/crates/router/src/services/kafka/refund_event.rs +++ b/crates/router/src/services/kafka/refund_event.rs @@ -67,7 +67,7 @@ impl<'a> KafkaRefundEvent<'a> { } } -impl<'a> super::KafkaMessage for KafkaRefundEvent<'a> { +impl super::KafkaMessage for KafkaRefundEvent<'_> { fn key(&self) -> String { format!( "{}_{}_{}_{}", diff --git a/crates/router/src/services/logger.rs b/crates/router/src/services/logger.rs index 7dfd7abb8441..e88d4072f906 100644 --- a/crates/router/src/services/logger.rs +++ b/crates/router/src/services/logger.rs @@ -1,5 +1,3 @@ -//! //! Logger of the system. -//! pub use crate::logger::*; diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 467ae31f7cf1..95728bd04bc1 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -258,6 +258,7 @@ pub trait Capturable { } } +#[cfg(feature = "v1")] impl Capturable for PaymentsAuthorizeData { fn get_captured_amount(&self, payment_data: &PaymentData) -> Option where @@ -306,6 +307,7 @@ impl Capturable for PaymentsAuthorizeData { } } +#[cfg(feature = "v1")] impl Capturable for PaymentsCaptureData { fn get_captured_amount(&self, _payment_data: &PaymentData) -> Option where @@ -338,6 +340,7 @@ impl Capturable for PaymentsCaptureData { } } +#[cfg(feature = "v1")] impl Capturable for CompleteAuthorizeData { fn get_captured_amount(&self, payment_data: &PaymentData) -> Option where @@ -386,6 +389,7 @@ impl Capturable for CompleteAuthorizeData { } } } + impl Capturable for SetupMandateRequestData {} impl Capturable for PaymentsTaxCalculationData {} impl Capturable for SdkPaymentsSessionUpdateData {} diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index f5fa2d9a37eb..975b219a26ca 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -367,7 +367,7 @@ impl ConnectorData { Ok(ConnectorEnum::Old(Box::new(connector::Cryptopay::new()))) } enums::Connector::Cybersource => { - Ok(ConnectorEnum::Old(Box::new(&connector::Cybersource))) + Ok(ConnectorEnum::Old(Box::new(connector::Cybersource::new()))) } enums::Connector::Datatrans => { Ok(ConnectorEnum::Old(Box::new(connector::Datatrans::new()))) diff --git a/crates/router/src/types/storage/payment_link.rs b/crates/router/src/types/storage/payment_link.rs index 9a251d760bd6..ae9aa4173266 100644 --- a/crates/router/src/types/storage/payment_link.rs +++ b/crates/router/src/types/storage/payment_link.rs @@ -11,8 +11,8 @@ use crate::{ core::errors::{self, CustomResult}, logger, }; -#[async_trait::async_trait] +#[async_trait::async_trait] pub trait PaymentLinkDbExt: Sized { async fn filter_by_constraints( conn: &PgPooledConn, diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 4ae026689579..55a523b528eb 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -701,7 +701,7 @@ impl ForeignFrom for api_types::Config { } } -impl<'a> ForeignFrom<&'a api_types::ConfigUpdate> for storage::ConfigUpdate { +impl ForeignFrom<&api_types::ConfigUpdate> for storage::ConfigUpdate { fn foreign_from(config: &api_types::ConfigUpdate) -> Self { Self::Update { config: Some(config.value.clone()), @@ -709,7 +709,7 @@ impl<'a> ForeignFrom<&'a api_types::ConfigUpdate> for storage::ConfigUpdate { } } -impl<'a> From<&'a domain::Address> for api_types::Address { +impl From<&domain::Address> for hyperswitch_domain_models::address::Address { fn from(address: &domain::Address) -> Self { // If all the fields of address are none, then pass the address as None let address_details = if address.city.is_none() @@ -724,7 +724,7 @@ impl<'a> From<&'a domain::Address> for api_types::Address { { None } else { - Some(api_types::AddressDetails { + Some(hyperswitch_domain_models::address::AddressDetails { city: address.city.clone(), country: address.country, line1: address.line1.clone().map(Encryptable::into_inner), @@ -741,7 +741,7 @@ impl<'a> From<&'a domain::Address> for api_types::Address { let phone_details = if address.phone_number.is_none() && address.country_code.is_none() { None } else { - Some(api_types::PhoneDetails { + Some(hyperswitch_domain_models::address::PhoneDetails { number: address.phone_number.clone().map(Encryptable::into_inner), country_code: address.country_code.clone(), }) @@ -1553,7 +1553,9 @@ impl field_name: "customer_details", })?; - let mut billing_address = billing.map(api_types::Address::from); + let mut billing_address = billing + .map(hyperswitch_domain_models::address::Address::from) + .map(api_types::Address::from); // This change is to fix a merchant integration // If billing.email is not passed by the merchant, and if the customer email is present, then use the `customer.email` as the billing email @@ -1582,7 +1584,9 @@ impl Ok(Self { currency: payment_attempt.map(|pa| pa.currency.unwrap_or_default()), - shipping: shipping.map(api_types::Address::from), + shipping: shipping + .map(hyperswitch_domain_models::address::Address::from) + .map(api_types::Address::from), billing: billing_address, amount: payment_attempt .map(|pa| api_types::Amount::from(pa.net_amount.get_order_amount())), @@ -1686,6 +1690,7 @@ impl ForeignFrom for storage::GatewayStatusMapp step_up_possible: value.step_up_possible, unified_code: value.unified_code, unified_message: value.unified_message, + error_category: value.error_category, } } } @@ -1704,6 +1709,7 @@ impl ForeignFrom for gsm_api_types::GsmResponse { step_up_possible: value.step_up_possible, unified_code: value.unified_code, unified_message: value.unified_message, + error_category: value.error_category, } } } diff --git a/crates/router/src/utils/user.rs b/crates/router/src/utils/user.rs index 443db741ae34..281b95255c86 100644 --- a/crates/router/src/utils/user.rs +++ b/crates/router/src/utils/user.rs @@ -27,6 +27,7 @@ pub mod dashboard_metadata; pub mod password; #[cfg(feature = "dummy_connector")] pub mod sample_data; +pub mod theme; pub mod two_factor_auth; impl UserFromToken { diff --git a/crates/router/src/utils/user/theme.rs b/crates/router/src/utils/user/theme.rs new file mode 100644 index 000000000000..13452380d9d9 --- /dev/null +++ b/crates/router/src/utils/user/theme.rs @@ -0,0 +1,158 @@ +use std::path::PathBuf; + +use common_utils::{id_type, types::theme::ThemeLineage}; +use error_stack::ResultExt; +use hyperswitch_domain_models::merchant_key_store::MerchantKeyStore; + +use crate::{ + core::errors::{StorageErrorExt, UserErrors, UserResult}, + routes::SessionState, +}; + +fn get_theme_dir_key(theme_id: &str) -> PathBuf { + ["themes", theme_id].iter().collect() +} + +pub fn get_specific_file_key(theme_id: &str, file_name: &str) -> PathBuf { + let mut path = get_theme_dir_key(theme_id); + path.push(file_name); + path +} + +pub fn get_theme_file_key(theme_id: &str) -> PathBuf { + get_specific_file_key(theme_id, "theme.json") +} + +fn path_buf_to_str(path: &PathBuf) -> UserResult<&str> { + path.to_str() + .ok_or(UserErrors::InternalServerError) + .attach_printable(format!("Failed to convert path {:#?} to string", path)) +} + +pub async fn retrieve_file_from_theme_bucket( + state: &SessionState, + path: &PathBuf, +) -> UserResult> { + state + .theme_storage_client + .retrieve_file(path_buf_to_str(path)?) + .await + .change_context(UserErrors::ErrorRetrievingFile) +} + +pub async fn upload_file_to_theme_bucket( + state: &SessionState, + path: &PathBuf, + data: Vec, +) -> UserResult<()> { + state + .theme_storage_client + .upload_file(path_buf_to_str(path)?, data) + .await + .change_context(UserErrors::ErrorUploadingFile) +} + +pub async fn validate_lineage(state: &SessionState, lineage: &ThemeLineage) -> UserResult<()> { + match lineage { + ThemeLineage::Organization { tenant_id, org_id } => { + validate_tenant(state, tenant_id)?; + validate_org(state, org_id).await?; + Ok(()) + } + ThemeLineage::Merchant { + tenant_id, + org_id, + merchant_id, + } => { + validate_tenant(state, tenant_id)?; + validate_org(state, org_id).await?; + validate_merchant(state, org_id, merchant_id).await?; + Ok(()) + } + ThemeLineage::Profile { + tenant_id, + org_id, + merchant_id, + profile_id, + } => { + validate_tenant(state, tenant_id)?; + validate_org(state, org_id).await?; + let key_store = validate_merchant_and_get_key_store(state, org_id, merchant_id).await?; + validate_profile(state, profile_id, merchant_id, &key_store).await?; + Ok(()) + } + } +} + +fn validate_tenant(state: &SessionState, tenant_id: &id_type::TenantId) -> UserResult<()> { + if &state.tenant.tenant_id != tenant_id { + return Err(UserErrors::InvalidThemeLineage("tenant_id".to_string()).into()); + } + Ok(()) +} + +async fn validate_org(state: &SessionState, org_id: &id_type::OrganizationId) -> UserResult<()> { + state + .store + .find_organization_by_org_id(org_id) + .await + .to_not_found_response(UserErrors::InvalidThemeLineage("org_id".to_string()))?; + Ok(()) +} + +async fn validate_merchant_and_get_key_store( + state: &SessionState, + org_id: &id_type::OrganizationId, + merchant_id: &id_type::MerchantId, +) -> UserResult { + let key_store = state + .store + .get_merchant_key_store_by_merchant_id( + &state.into(), + merchant_id, + &state.store.get_master_key().to_vec().into(), + ) + .await + .to_not_found_response(UserErrors::InvalidThemeLineage("merchant_id".to_string()))?; + + let merchant_account = state + .store + .find_merchant_account_by_merchant_id(&state.into(), merchant_id, &key_store) + .await + .to_not_found_response(UserErrors::InvalidThemeLineage("merchant_id".to_string()))?; + + if &merchant_account.organization_id != org_id { + return Err(UserErrors::InvalidThemeLineage("merchant_id".to_string()).into()); + } + + Ok(key_store) +} + +async fn validate_merchant( + state: &SessionState, + org_id: &id_type::OrganizationId, + merchant_id: &id_type::MerchantId, +) -> UserResult<()> { + validate_merchant_and_get_key_store(state, org_id, merchant_id) + .await + .map(|_| ()) +} + +async fn validate_profile( + state: &SessionState, + profile_id: &id_type::ProfileId, + merchant_id: &id_type::MerchantId, + key_store: &MerchantKeyStore, +) -> UserResult<()> { + state + .store + .find_business_profile_by_merchant_id_profile_id( + &state.into(), + key_store, + merchant_id, + profile_id, + ) + .await + .to_not_found_response(UserErrors::InvalidThemeLineage("profile_id".to_string()))?; + Ok(()) +} diff --git a/crates/router/src/utils/user_role.rs b/crates/router/src/utils/user_role.rs index 0bd0e81149f5..8acab4364911 100644 --- a/crates/router/src/utils/user_role.rs +++ b/crates/router/src/utils/user_role.rs @@ -25,7 +25,7 @@ pub fn validate_role_groups(groups: &[PermissionGroup]) -> UserResult<()> { .attach_printable("Role groups cannot be empty"); } - let unique_groups: HashSet<_> = groups.iter().cloned().collect(); + let unique_groups: HashSet<_> = groups.iter().copied().collect(); if unique_groups.contains(&PermissionGroup::OrganizationManage) { return Err(report!(UserErrors::InvalidRoleOperation)) diff --git a/crates/router/src/workflows/payment_sync.rs b/crates/router/src/workflows/payment_sync.rs index b4fcf69241b8..04fa16484922 100644 --- a/crates/router/src/workflows/payment_sync.rs +++ b/crates/router/src/workflows/payment_sync.rs @@ -243,7 +243,6 @@ impl ProcessTrackerWorkflow for PaymentsSyncWorkflow { /// `start_after`: The first psync should happen after 60 seconds /// /// `frequency` and `count`: The next 5 retries should have an interval of 300 seconds between them -/// pub async fn get_sync_process_schedule_time( db: &dyn StorageInterface, connector: &str, diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs index 92cba2eec3f0..d8607946b500 100644 --- a/crates/router/tests/connectors/aci.rs +++ b/crates/router/tests/connectors/aci.rs @@ -2,8 +2,8 @@ use std::{borrow::Cow, marker::PhantomData, str::FromStr, sync::Arc}; -use api_models::payments::{Address, AddressDetails, PhoneDetails}; use common_utils::id_type; +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::{ configs::settings::Settings, @@ -205,7 +205,6 @@ fn construct_refund_router_data() -> types::RefundsRouterData { } #[actix_web::test] - async fn payments_create_success() { let conf = Settings::new().unwrap(); let tx: oneshot::Sender<()> = oneshot::channel().0; @@ -314,7 +313,6 @@ async fn payments_create_failure() { } #[actix_web::test] - async fn refund_for_successful_payments() { let conf = Settings::new().unwrap(); use router::connector::Aci; diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs index 2e8d4ab6862a..2146d9590020 100644 --- a/crates/router/tests/connectors/adyen.rs +++ b/crates/router/tests/connectors/adyen.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails, PhoneDetails}; +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, storage::enums, PaymentAddress}; diff --git a/crates/router/tests/connectors/airwallex.rs b/crates/router/tests/connectors/airwallex.rs index f46a0cf7597f..bbc387a0b226 100644 --- a/crates/router/tests/connectors/airwallex.rs +++ b/crates/router/tests/connectors/airwallex.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails}; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::{PeekInterface, Secret}; use router::types::{self, domain, storage::enums, AccessToken}; diff --git a/crates/router/tests/connectors/bitpay.rs b/crates/router/tests/connectors/bitpay.rs index 43959fa683cb..70af3b752127 100644 --- a/crates/router/tests/connectors/bitpay.rs +++ b/crates/router/tests/connectors/bitpay.rs @@ -1,3 +1,4 @@ +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, PaymentAddress}; @@ -40,8 +41,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -51,7 +52,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/bluesnap.rs b/crates/router/tests/connectors/bluesnap.rs index 73799693d74b..d6df20d7ee0e 100644 --- a/crates/router/tests/connectors/bluesnap.rs +++ b/crates/router/tests/connectors/bluesnap.rs @@ -1,7 +1,7 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails}; use common_utils::pii::Email; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, domain, storage::enums, ConnectorAuthType, PaymentAddress}; diff --git a/crates/router/tests/connectors/cashtocode.rs b/crates/router/tests/connectors/cashtocode.rs index 7656cd67de51..50c93f05a6b8 100644 --- a/crates/router/tests/connectors/cashtocode.rs +++ b/crates/router/tests/connectors/cashtocode.rs @@ -1,5 +1,5 @@ -use api_models::payments::{Address, AddressDetails}; use common_utils::id_type; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use router::types::{self, domain, storage::enums}; use crate::{ diff --git a/crates/router/tests/connectors/coinbase.rs b/crates/router/tests/connectors/coinbase.rs index 20be2e502baf..7320b875ca25 100644 --- a/crates/router/tests/connectors/coinbase.rs +++ b/crates/router/tests/connectors/coinbase.rs @@ -1,3 +1,4 @@ +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, PaymentAddress}; use serde_json::json; @@ -41,8 +42,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -52,7 +53,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/cryptopay.rs b/crates/router/tests/connectors/cryptopay.rs index b5f57f7d6f5c..2ecc7869bcd2 100644 --- a/crates/router/tests/connectors/cryptopay.rs +++ b/crates/router/tests/connectors/cryptopay.rs @@ -1,3 +1,4 @@ +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, PaymentAddress}; @@ -40,8 +41,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -51,7 +52,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/cybersource.rs b/crates/router/tests/connectors/cybersource.rs index 0116b52f4edc..08001ddd782c 100644 --- a/crates/router/tests/connectors/cybersource.rs +++ b/crates/router/tests/connectors/cybersource.rs @@ -1,6 +1,7 @@ use std::str::FromStr; use common_utils::pii::Email; +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums}; @@ -14,7 +15,7 @@ impl utils::Connector for Cybersource { fn get_data(&self) -> api::ConnectorData { use router::connector::Cybersource; utils::construct_connector_data_old( - Box::new(&Cybersource), + Box::new(Cybersource::new()), types::Connector::Cybersource, api::GetToken::Connector, None, @@ -37,8 +38,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -48,7 +49,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/dlocal.rs b/crates/router/tests/connectors/dlocal.rs index 62278d30ca75..3022f1f0b1d8 100644 --- a/crates/router/tests/connectors/dlocal.rs +++ b/crates/router/tests/connectors/dlocal.rs @@ -2,7 +2,7 @@ use std::str::FromStr; -use api_models::payments::Address; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, PaymentAddress}; @@ -426,7 +426,7 @@ pub fn get_payment_info() -> PaymentInfo { None, Some(Address { phone: None, - address: Some(api::AddressDetails { + address: Some(AddressDetails { city: None, country: Some(api_models::enums::CountryAlpha2::PA), line1: None, diff --git a/crates/router/tests/connectors/forte.rs b/crates/router/tests/connectors/forte.rs index fa084fc4b2c7..3c5cde492c0c 100644 --- a/crates/router/tests/connectors/forte.rs +++ b/crates/router/tests/connectors/forte.rs @@ -2,6 +2,7 @@ use std::{str::FromStr, time::Duration}; use cards::CardNumber; use common_utils::types::MinorUnit; +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums}; @@ -54,8 +55,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -65,7 +66,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/globalpay.rs b/crates/router/tests/connectors/globalpay.rs index 8879631d1e3d..cd7e6c6b7991 100644 --- a/crates/router/tests/connectors/globalpay.rs +++ b/crates/router/tests/connectors/globalpay.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, AccessToken, ConnectorAuthType}; use serde_json::json; @@ -59,8 +60,8 @@ impl Globalpay { Some(PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { country: Some(api_models::enums::CountryAlpha2::US), ..Default::default() }), diff --git a/crates/router/tests/connectors/iatapay.rs b/crates/router/tests/connectors/iatapay.rs index 577da6ce6852..d216f6063f6d 100644 --- a/crates/router/tests/connectors/iatapay.rs +++ b/crates/router/tests/connectors/iatapay.rs @@ -1,3 +1,4 @@ +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, storage::enums, AccessToken}; @@ -57,8 +58,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -68,7 +69,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::NL), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/multisafepay.rs b/crates/router/tests/connectors/multisafepay.rs index 0d5af818c358..1a81b00116fa 100644 --- a/crates/router/tests/connectors/multisafepay.rs +++ b/crates/router/tests/connectors/multisafepay.rs @@ -1,4 +1,4 @@ -use api_models::payments::{Address, AddressDetails}; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, domain, storage::enums, PaymentAddress}; diff --git a/crates/router/tests/connectors/opennode.rs b/crates/router/tests/connectors/opennode.rs index e8778f9f4233..d2629e287ca6 100644 --- a/crates/router/tests/connectors/opennode.rs +++ b/crates/router/tests/connectors/opennode.rs @@ -1,3 +1,4 @@ +use hyperswitch_domain_models::address::{Address, AddressDetails, PhoneDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums}; @@ -40,8 +41,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), @@ -51,7 +52,7 @@ fn get_default_payment_info() -> Option { country: Some(api_models::enums::CountryAlpha2::IN), ..Default::default() }), - phone: Some(api::PhoneDetails { + phone: Some(PhoneDetails { number: Some(Secret::new("9123456789".to_string())), country_code: Some("+91".to_string()), }), diff --git a/crates/router/tests/connectors/payeezy.rs b/crates/router/tests/connectors/payeezy.rs index 1bc81ebfe257..49f7085bda49 100644 --- a/crates/router/tests/connectors/payeezy.rs +++ b/crates/router/tests/connectors/payeezy.rs @@ -1,7 +1,7 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails}; use cards::CardNumber; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::{ core::errors, diff --git a/crates/router/tests/connectors/payme.rs b/crates/router/tests/connectors/payme.rs index dbc3795e7f15..1994acb6a659 100644 --- a/crates/router/tests/connectors/payme.rs +++ b/crates/router/tests/connectors/payme.rs @@ -1,8 +1,8 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails}; use common_utils::{pii::Email, types::MinorUnit}; use diesel_models::types::OrderDetailsWithAmount; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, domain, storage::enums, PaymentAddress}; diff --git a/crates/router/tests/connectors/trustpay.rs b/crates/router/tests/connectors/trustpay.rs index bae62913a9a3..308bf5135855 100644 --- a/crates/router/tests/connectors/trustpay.rs +++ b/crates/router/tests/connectors/trustpay.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::types::{self, api, domain, storage::enums, BrowserInformation}; @@ -69,8 +70,8 @@ fn get_default_payment_info() -> Option { Some(utils::PaymentInfo { address: Some(types::PaymentAddress::new( None, - Some(api::Address { - address: Some(api::AddressDetails { + Some(Address { + address: Some(AddressDetails { first_name: Some(Secret::new("first".to_string())), last_name: Some(Secret::new("last".to_string())), line1: Some(Secret::new("line1".to_string())), diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index f8f71a98283a..c08139ae6fe0 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -78,8 +78,8 @@ impl PaymentInfo { address: Some(PaymentAddress::new( None, None, - Some(types::api::Address { - address: Some(types::api::AddressDetails { + Some(hyperswitch_domain_models::address::Address { + address: Some(hyperswitch_domain_models::address::AddressDetails { first_name: Some(Secret::new("John".to_string())), last_name: Some(Secret::new("Doe".to_string())), ..Default::default() diff --git a/crates/router/tests/connectors/wise.rs b/crates/router/tests/connectors/wise.rs index 984a43d48a76..2156cfb1476c 100644 --- a/crates/router/tests/connectors/wise.rs +++ b/crates/router/tests/connectors/wise.rs @@ -1,4 +1,4 @@ -use api_models::payments::{Address, AddressDetails}; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::{ types, diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs index 73e710eb2f19..c1be90b59fde 100644 --- a/crates/router/tests/connectors/worldline.rs +++ b/crates/router/tests/connectors/worldline.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use api_models::payments::{Address, AddressDetails}; +use hyperswitch_domain_models::address::{Address, AddressDetails}; use masking::Secret; use router::{ connector::Worldline, diff --git a/crates/router_derive/src/lib.rs b/crates/router_derive/src/lib.rs index 33edd5e215e0..d1fb543318f2 100644 --- a/crates/router_derive/src/lib.rs +++ b/crates/router_derive/src/lib.rs @@ -166,7 +166,6 @@ pub fn diesel_enum( /// } /// ``` /// - /// # Panics /// /// Panics if a struct without named fields is provided as input to the macro @@ -505,7 +504,6 @@ pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre /// payment_method: String, /// } /// ``` - #[proc_macro_derive( PolymorphicSchema, attributes(mandatory_in, generate_schemas, remove_in) @@ -620,6 +618,7 @@ pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::Token /// /// Example /// +/// ``` /// #[derive(Default, Serialize, FlatStruct)] /// pub struct User { /// name: String, @@ -644,7 +643,7 @@ pub fn try_get_enum_variant(input: proc_macro::TokenStream) -> proc_macro::Token /// ("address.zip", "941222"), /// ("email", "test@example.com"), /// ] -/// +/// ``` #[proc_macro_derive(FlatStruct)] pub fn flat_struct_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse_macro_input!(input as syn::DeriveInput); diff --git a/crates/router_derive/src/macros/operation.rs b/crates/router_derive/src/macros/operation.rs index 407e910b29d1..a096c236b2f2 100644 --- a/crates/router_derive/src/macros/operation.rs +++ b/crates/router_derive/src/macros/operation.rs @@ -5,7 +5,7 @@ use quote::{quote, ToTokens}; use strum::IntoEnumIterator; use syn::{self, parse::Parse, DeriveInput}; -use crate::macros::helpers::{self}; +use crate::macros::helpers; #[derive(Debug, Clone, Copy, strum::EnumString, strum::EnumIter, strum::Display)] #[strum(serialize_all = "snake_case")] diff --git a/crates/router_env/src/lib.rs b/crates/router_env/src/lib.rs index 0d46f8ac3325..9b3aec4c949b 100644 --- a/crates/router_env/src/lib.rs +++ b/crates/router_env/src/lib.rs @@ -1,8 +1,6 @@ #![warn(missing_debug_implementations)] -//! //! Environment of payment router: logger, basic config, its environment awareness. -//! #![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR" ), "/", "README.md"))] diff --git a/crates/router_env/src/logger/mod.rs b/crates/router_env/src/logger.rs similarity index 98% rename from crates/router_env/src/logger/mod.rs rename to crates/router_env/src/logger.rs index a7aa0610e9b4..2b0ae49b1f65 100644 --- a/crates/router_env/src/logger/mod.rs +++ b/crates/router_env/src/logger.rs @@ -1,6 +1,4 @@ -//! //! Logger of the system. -//! pub use tracing::{debug, error, event as log, info, warn}; pub use tracing_attributes::instrument; diff --git a/crates/router_env/src/logger/config.rs b/crates/router_env/src/logger/config.rs index 03cc9ac17bc8..746c8ee9580a 100644 --- a/crates/router_env/src/logger/config.rs +++ b/crates/router_env/src/logger/config.rs @@ -1,6 +1,4 @@ -//! //! Logger-specific config. -//! use std::path::PathBuf; diff --git a/crates/router_env/src/logger/formatter.rs b/crates/router_env/src/logger/formatter.rs index 6bcf669e73a7..5c3341026c20 100644 --- a/crates/router_env/src/logger/formatter.rs +++ b/crates/router_env/src/logger/formatter.rs @@ -1,6 +1,4 @@ -//! //! Formatting [layer](https://docs.rs/tracing-subscriber/0.3.15/tracing_subscriber/layer/trait.Layer.html) for Router. -//! use std::{ collections::{HashMap, HashSet}, @@ -117,10 +115,8 @@ impl fmt::Display for RecordType { } } -/// /// Format log records. /// `FormattingLayer` relies on the `tracing_bunyan_formatter::JsonStorageLayer` which is storage of entries. -/// #[derive(Debug)] pub struct FormattingLayer where @@ -145,7 +141,6 @@ where W: for<'a> MakeWriter<'a> + 'static, F: Formatter + Clone, { - /// /// Constructor of `FormattingLayer`. /// /// A `name` will be attached to all records during formatting. @@ -155,7 +150,6 @@ where /// ```rust /// let formatting_layer = router_env::FormattingLayer::new("my_service", std::io::stdout, serde_json::ser::CompactFormatter); /// ``` - /// pub fn new( service: &str, dst_writer: W, @@ -296,11 +290,9 @@ where Ok(()) } - /// /// Flush memory buffer into an output stream trailing it with next line. /// /// Should be done by single `write_all` call to avoid fragmentation of log because of mutlithreading. - /// fn flush(&self, mut buffer: Vec) -> Result<(), std::io::Error> { buffer.write_all(b"\n")?; self.dst_writer.make_writer().write_all(&buffer) @@ -361,12 +353,9 @@ where Ok(buffer) } - /// /// Format message of a span. /// /// Example: "[FN_WITHOUT_COLON - START]" - /// - fn span_message(span: &SpanRef<'_, S>, ty: RecordType) -> String where S: Subscriber + for<'a> LookupSpan<'a>, @@ -374,12 +363,9 @@ where format!("[{} - {}]", span.metadata().name().to_uppercase(), ty) } - /// /// Format message of an event. /// /// Examples: "[FN_WITHOUT_COLON - EVENT] Message" - /// - fn event_message( span: &Option<&SpanRef<'_, S>>, event: &Event<'_>, diff --git a/crates/router_env/src/logger/setup.rs b/crates/router_env/src/logger/setup.rs index 428112fb37c3..6433172edf4d 100644 --- a/crates/router_env/src/logger/setup.rs +++ b/crates/router_env/src/logger/setup.rs @@ -181,9 +181,7 @@ struct TraceAssertion { } impl TraceAssertion { - /// /// Should the provided url be traced - /// fn should_trace_url(&self, url: &str) -> bool { match &self.clauses { Some(clauses) => clauses.iter().all(|cur| cur.compare_url(url)), @@ -192,9 +190,7 @@ impl TraceAssertion { } } -/// /// Conditional Sampler for providing control on url based tracing -/// #[derive(Clone, Debug)] struct ConditionalSampler(TraceAssertion, T); diff --git a/crates/router_env/src/logger/storage.rs b/crates/router_env/src/logger/storage.rs index ce220680bb15..cdaf06ecf93a 100644 --- a/crates/router_env/src/logger/storage.rs +++ b/crates/router_env/src/logger/storage.rs @@ -1,6 +1,4 @@ -//! //! Storing [layer](https://docs.rs/tracing-subscriber/0.3.15/tracing_subscriber/layer/trait.Layer.html) for Router. -//! use std::{collections::HashMap, fmt, time::Instant}; diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs index 5d59e7ddbac4..0330c43aa457 100644 --- a/crates/router_env/src/logger/types.rs +++ b/crates/router_env/src/logger/types.rs @@ -1,6 +1,4 @@ -//! //! Types. -//! use serde::Deserialize; use strum::{Display, EnumString}; @@ -9,12 +7,9 @@ pub use tracing::{ Level, Value, }; -/// /// Category and tag of log event. /// /// Don't hesitate to add your variant if it is missing here. -/// - #[derive(Debug, Default, Deserialize, Clone, Display, EnumString)] pub enum Tag { /// General. @@ -488,6 +483,18 @@ pub enum Flow { ListUsersInLineage, /// List invitations for user ListInvitationsForUser, + /// Get theme using lineage + GetThemeUsingLineage, + /// Get theme using theme id + GetThemeUsingThemeId, + /// Upload file to theme storage + UploadFileToThemeStorage, + /// Create theme + CreateTheme, + /// Update theme + UpdateTheme, + /// Delete theme + DeleteTheme, /// List initial webhook delivery attempts WebhookEventInitialDeliveryAttemptList, /// List delivery attempts for a webhook event @@ -516,9 +523,7 @@ pub enum Flow { PaymentStartRedirection, } -/// /// Trait for providing generic behaviour to flow metric -/// pub trait FlowMetric: ToString + std::fmt::Debug + Clone {} impl FlowMetric for Flow {} diff --git a/crates/router_env/tests/logger.rs b/crates/router_env/tests/logger.rs index 46b5b9538cf7..1070938a8a10 100644 --- a/crates/router_env/tests/logger.rs +++ b/crates/router_env/tests/logger.rs @@ -1,10 +1,11 @@ #![allow(clippy::unwrap_used)] mod test_module; + use ::config::ConfigError; use router_env::TelemetryGuard; -use self::test_module::some_module::*; +use self::test_module::fn_with_colon; fn logger() -> error_stack::Result<&'static TelemetryGuard, ConfigError> { use once_cell::sync::OnceCell; diff --git a/crates/router_env/tests/test_module/some_module.rs b/crates/router_env/tests/test_module.rs similarity index 90% rename from crates/router_env/tests/test_module/some_module.rs rename to crates/router_env/tests/test_module.rs index 8c9dda2c08e6..f3c382706b4d 100644 --- a/crates/router_env/tests/test_module/some_module.rs +++ b/crates/router_env/tests/test_module.rs @@ -1,7 +1,6 @@ -use logger::instrument; use router_env as logger; -#[instrument(skip_all)] +#[tracing::instrument(skip_all)] pub async fn fn_with_colon(val: i32) { let a = 13; let b = 31; @@ -23,7 +22,7 @@ pub async fn fn_with_colon(val: i32) { fn_without_colon(131).await; } -#[instrument(fields(val3 = "abc"), skip_all)] +#[tracing::instrument(fields(val3 = "abc"), skip_all)] pub async fn fn_without_colon(val: i32) { let a = 13; let b = 31; diff --git a/crates/router_env/tests/test_module/mod.rs b/crates/router_env/tests/test_module/mod.rs deleted file mode 100644 index 7699174549da..000000000000 --- a/crates/router_env/tests/test_module/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod some_module; diff --git a/crates/scheduler/src/db/mod.rs b/crates/scheduler/src/db.rs similarity index 100% rename from crates/scheduler/src/db/mod.rs rename to crates/scheduler/src/db.rs diff --git a/crates/storage_impl/src/mock_db.rs b/crates/storage_impl/src/mock_db.rs index efcce5677270..b81676a6cc4f 100644 --- a/crates/storage_impl/src/mock_db.rs +++ b/crates/storage_impl/src/mock_db.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use diesel_models::{self as store}; +use diesel_models as store; use error_stack::ResultExt; use futures::lock::Mutex; use hyperswitch_domain_models::{ diff --git a/crates/storage_impl/src/redis/cache.rs b/crates/storage_impl/src/redis/cache.rs index 699310579594..fff5435fc74d 100644 --- a/crates/storage_impl/src/redis/cache.rs +++ b/crates/storage_impl/src/redis/cache.rs @@ -72,7 +72,7 @@ pub static PM_FILTERS_CGRAPH_CACHE: Lazy = Lazy::new(|| { ) }); -/// Dynamic Algorithm Cache +/// Success based Dynamic Algorithm Cache pub static SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE: Lazy = Lazy::new(|| { Cache::new( "SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE", @@ -82,6 +82,16 @@ pub static SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE: Lazy = Lazy::new(|| { ) }); +/// Elimination based Dynamic Algorithm Cache +pub static ELIMINATION_BASED_DYNAMIC_ALGORITHM_CACHE: Lazy = Lazy::new(|| { + Cache::new( + "ELIMINATION_BASED_DYNAMIC_ALGORITHM_CACHE", + CACHE_TTL, + CACHE_TTI, + Some(MAX_CAPACITY), + ) +}); + /// Trait which defines the behaviour of types that's gonna be stored in Cache pub trait Cacheable: Any + Send + Sync + DynClone { fn as_any(&self) -> &dyn Any; @@ -102,6 +112,7 @@ pub enum CacheKind<'a> { Surcharge(Cow<'a, str>), CGraph(Cow<'a, str>), SuccessBasedDynamicRoutingCache(Cow<'a, str>), + EliminationBasedDynamicRoutingCache(Cow<'a, str>), PmFiltersCGraph(Cow<'a, str>), All(Cow<'a, str>), } @@ -117,7 +128,7 @@ impl<'a> TryFrom> for RedisValue { } } -impl<'a> TryFrom for CacheRedact<'a> { +impl TryFrom for CacheRedact<'_> { type Error = Report; fn try_from(v: RedisValue) -> Result { diff --git a/crates/storage_impl/src/redis/kv_store.rs b/crates/storage_impl/src/redis/kv_store.rs index 2fde935b670d..83d8de9c30ac 100644 --- a/crates/storage_impl/src/redis/kv_store.rs +++ b/crates/storage_impl/src/redis/kv_store.rs @@ -57,7 +57,7 @@ pub enum PartitionKey<'a> { }, } // PartitionKey::MerchantIdPaymentId {merchant_id, payment_id} -impl<'a> std::fmt::Display for PartitionKey<'a> { +impl std::fmt::Display for PartitionKey<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match *self { PartitionKey::MerchantIdPaymentId { @@ -279,7 +279,7 @@ pub enum Op<'a> { Find, } -impl<'a> std::fmt::Display for Op<'a> { +impl std::fmt::Display for Op<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Op::Insert => f.write_str("insert"), diff --git a/crates/storage_impl/src/redis/pub_sub.rs b/crates/storage_impl/src/redis/pub_sub.rs index 6a2012f9b26f..42ad2ae0795a 100644 --- a/crates/storage_impl/src/redis/pub_sub.rs +++ b/crates/storage_impl/src/redis/pub_sub.rs @@ -6,8 +6,8 @@ use router_env::{logger, tracing::Instrument}; use crate::redis::cache::{ CacheKey, CacheKind, CacheRedact, ACCOUNTS_CACHE, CGRAPH_CACHE, CONFIG_CACHE, - DECISION_MANAGER_CACHE, PM_FILTERS_CGRAPH_CACHE, ROUTING_CACHE, - SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE, SURCHARGE_CACHE, + DECISION_MANAGER_CACHE, ELIMINATION_BASED_DYNAMIC_ALGORITHM_CACHE, PM_FILTERS_CGRAPH_CACHE, + ROUTING_CACHE, SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE, SURCHARGE_CACHE, }; #[async_trait::async_trait] @@ -138,6 +138,15 @@ impl PubSubInterface for std::sync::Arc { .await; key } + CacheKind::EliminationBasedDynamicRoutingCache(key) => { + ELIMINATION_BASED_DYNAMIC_ALGORITHM_CACHE + .remove(CacheKey { + key: key.to_string(), + prefix: message.tenant.clone(), + }) + .await; + key + } CacheKind::SuccessBasedDynamicRoutingCache(key) => { SUCCESS_BASED_DYNAMIC_ALGORITHM_CACHE .remove(CacheKey { @@ -205,6 +214,12 @@ impl PubSubInterface for std::sync::Arc { prefix: message.tenant.clone(), }) .await; + ELIMINATION_BASED_DYNAMIC_ALGORITHM_CACHE + .remove(CacheKey { + key: key.to_string(), + prefix: message.tenant.clone(), + }) + .await; ROUTING_CACHE .remove(CacheKey { key: key.to_string(), diff --git a/cypress-tests/.gitignore b/cypress-tests/.gitignore index 69b344a1d968..663fbaa3f4df 100644 --- a/cypress-tests/.gitignore +++ b/cypress-tests/.gitignore @@ -1,3 +1,4 @@ +.DS_Store creds.json reports run_all.sh diff --git a/cypress-tests/.prettierrc b/cypress-tests/.prettierrc new file mode 100644 index 000000000000..729684105779 --- /dev/null +++ b/cypress-tests/.prettierrc @@ -0,0 +1,9 @@ +{ + "bracketSpacing": true, + "endOfLine": "auto", + "printWidth": 80, + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "es5" +} diff --git a/cypress-tests/.prettierrc.json b/cypress-tests/.prettierrc.json deleted file mode 100644 index f0eb61e0f7c6..000000000000 --- a/cypress-tests/.prettierrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "trailingComma": "es5", - "tabWidth": 2, - "semi": true, - "singleQuote": false -} diff --git a/cypress-tests/cypress.config.js b/cypress-tests/cypress.config.js index ab71597f7fa7..56f6887761a7 100644 --- a/cypress-tests/cypress.config.js +++ b/cypress-tests/cypress.config.js @@ -1,18 +1,16 @@ -const { defineConfig } = require("cypress"); -const fs = require("fs-extra"); -const path = require("path"); +import { defineConfig } from "cypress"; +import "cypress-mochawesome-reporter/plugin.js"; let globalState; + // Fetch from environment variable const connectorId = process.env.CYPRESS_CONNECTOR || "service"; const screenshotsFolderName = `screenshots/${connectorId}`; const reportName = process.env.REPORT_NAME || `${connectorId}_report`; -module.exports = defineConfig({ +export default defineConfig({ e2e: { - setupNodeEvents(on, config) { - require("cypress-mochawesome-reporter/plugin")(on); - + setupNodeEvents(on) { on("task", { setGlobalState: (val) => { return (globalState = val || {}); @@ -21,7 +19,9 @@ module.exports = defineConfig({ return globalState || {}; }, cli_log: (message) => { + // eslint-disable-next-line no-console console.log("Logging console message from task"); + // eslint-disable-next-line no-console console.log(message); return null; }, diff --git a/cypress-tests/cypress.env.json b/cypress-tests/cypress.env.json deleted file mode 100644 index 0967ef424bce..000000000000 --- a/cypress-tests/cypress.env.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js b/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js index af1f16195c60..89b27a6b2716 100644 --- a/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js +++ b/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js @@ -1,15 +1,13 @@ -import apiKeyCreateBody from "../../fixtures/create-api-key-body.json"; -import createConnectorBody from "../../fixtures/create-connector-body.json"; -import merchantCreateBody from "../../fixtures/merchant-create-body.json"; +import * as fixtures from "../../fixtures/imports"; import State from "../../utils/State"; import { - bank_redirect_ideal_and_credit_enabled, - bank_redirect_ideal_enabled, - card_credit_enabled, - card_credit_enabled_in_US, - card_credit_enabled_in_USD, - create_payment_body_with_currency, - create_payment_body_with_currency_country, + bankRedirectIdealAndCreditEnabled, + bankRedirectIdealEnabled, + cardCreditEnabled, + cardCreditEnabledInUs, + cardCreditEnabledInUsd, + createPaymentBodyWithCurrency, + createPaymentBodyWithCurrencyCountry, } from "../PaymentMethodListUtils/Commons"; import getConnectorDetails from "../PaymentMethodListUtils/Utils"; @@ -34,19 +32,22 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); + }); + it("customer-create-call-test", () => { + cy.createCustomerCallTest(fixtures.customerCreateBody, globalState); }); // stripe connector create with ideal enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_enabled, + fixtures.createConnectorBody, + bankRedirectIdealEnabled, globalState, "stripe", "stripe_US_default" @@ -57,8 +58,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled, + fixtures.createConnectorBody, + cardCreditEnabled, globalState, "cybersource", "cybersource_US_default" @@ -67,14 +68,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as EUR and no billing address it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyEUR"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyEUR, + RequestCurrencyEUR: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency("EUR"), - req_data, - res_data, + createPaymentBodyWithCurrency("EUR"), + newData, "no_three_ds", "automatic", globalState @@ -83,7 +87,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should only have ideal with stripe it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListWithStripeForIdeal" ]; @@ -114,19 +118,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with ideal enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_enabled, + fixtures.createConnectorBody, + bankRedirectIdealEnabled, globalState, "stripe", "stripe_US_default" @@ -137,8 +141,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled_in_USD, + fixtures.createConnectorBody, + cardCreditEnabledInUsd, globalState, "cybersource", "cybersource_US_default" @@ -147,14 +151,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as INR and no billing address it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyINR"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyINR, + RequestCurrencyINR: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency("INR"), - req_data, - res_data, + createPaymentBodyWithCurrency("INR"), + newData, "no_three_ds", "automatic", globalState @@ -163,7 +170,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should only have ideal with stripe it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListNull" ]; @@ -194,19 +201,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with credit enabled for US it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled_in_US, + fixtures.createConnectorBody, + cardCreditEnabledInUs, globalState, "stripe", "stripe_US_default" @@ -217,8 +224,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled_in_US, + fixtures.createConnectorBody, + cardCreditEnabledInUs, globalState, "cybersource", "cybersource_US_default" @@ -227,14 +234,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as USD and billing address as US it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyUSD"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyUSD, + RequestCurrencyUSD: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency("USD"), - req_data, - res_data, + createPaymentBodyWithCurrency("USD"), + newData, "no_three_ds", "automatic", globalState @@ -243,7 +253,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should only have credit with Stripe and Cybersource it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListWithCreditTwoConnector" ]; @@ -274,19 +284,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with ideal enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_enabled, + fixtures.createConnectorBody, + bankRedirectIdealEnabled, globalState, "stripe", "stripe_US_default" @@ -297,8 +307,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_enabled, + fixtures.createConnectorBody, + bankRedirectIdealEnabled, globalState, "cybersource", "cybersource_US_default" @@ -307,14 +317,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as EUR and billing address as US it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyEUR"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyEUR, + RequestCurrencyEUR: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency_country("EUR", "US", "US"), - req_data, - res_data, + createPaymentBodyWithCurrencyCountry("EUR", "US", "US"), + newData, "no_three_ds", "automatic", globalState @@ -323,7 +336,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which shouldn't have anything it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListNull" ]; @@ -356,19 +369,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with card credit enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled, + fixtures.createConnectorBody, + cardCreditEnabled, globalState, "stripe", "stripe_US_default" @@ -379,8 +392,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_and_credit_enabled, + fixtures.createConnectorBody, + bankRedirectIdealAndCreditEnabled, globalState, "cybersource", "cybersource_US_default" @@ -389,14 +402,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as USD and billing address as IN it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyUSD"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyUSD, + RequestCurrencyUSD: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency_country("USD", "IN", "IN"), - req_data, - res_data, + createPaymentBodyWithCurrencyCountry("USD", "IN", "IN"), + newData, "no_three_ds", "automatic", globalState @@ -405,7 +421,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should have credit with stripe and cybersource and no ideal it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListWithCreditTwoConnector" ]; @@ -437,19 +453,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with card credit enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled, + fixtures.createConnectorBody, + cardCreditEnabled, globalState, "stripe", "stripe_US_default" @@ -460,8 +476,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled, + fixtures.createConnectorBody, + cardCreditEnabled, globalState, "cybersource", "cybersource_US_default" @@ -470,14 +486,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as USD and billing address as IN it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyUSD"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyUSD, + RequestCurrencyUSD: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency("USD"), - req_data, - res_data, + createPaymentBodyWithCurrency("USD"), + newData, "no_three_ds", "automatic", globalState @@ -486,7 +505,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should have credit with stripe and cybersource and no ideal it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListWithCreditTwoConnector" ]; @@ -517,19 +536,19 @@ describe("Payment Method list using Constraint Graph flow tests", () => { }); it("merchant-create-call-test", () => { - cy.merchantCreateCallTest(merchantCreateBody, globalState); + cy.merchantCreateCallTest(fixtures.merchantCreateBody, globalState); }); it("api-key-create-call-test", () => { - cy.apiKeyCreateTest(apiKeyCreateBody, globalState); + cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState); }); // stripe connector create with ideal enabled it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - bank_redirect_ideal_enabled, + fixtures.createConnectorBody, + bankRedirectIdealEnabled, globalState, "stripe", "stripe_US_default" @@ -540,8 +559,8 @@ describe("Payment Method list using Constraint Graph flow tests", () => { it("connector-create-call-test", () => { cy.createNamedConnectorCallTest( "payment_processor", - createConnectorBody, - card_credit_enabled, + fixtures.createConnectorBody, + cardCreditEnabled, globalState, "cybersource", "cybersource_US_default" @@ -550,14 +569,17 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // creating payment with currency as EUR and no billing address it("create-payment-call-test", () => { - let data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; - let req_data = data["RequestCurrencyEUR"]; - let res_data = data["Response"]; + const data = getConnectorDetails("stripe")["pm_list"]["PaymentIntent"]; + + const newData = { + ...data, + Request: data.RequestCurrencyEUR, + RequestCurrencyEUR: undefined, // we do not need this anymore + }; cy.createPaymentIntentTest( - create_payment_body_with_currency_country("EUR", "NL", "US"), - req_data, - res_data, + createPaymentBodyWithCurrencyCountry("EUR", "NL", "US"), + newData, "no_three_ds", "automatic", globalState @@ -566,7 +588,7 @@ describe("Payment Method list using Constraint Graph flow tests", () => { // payment method list which should only have ideal with stripe it("payment-method-list-call-test", () => { - let data = + const data = getConnectorDetails("stripe")["pm_list"]["PmListResponse"][ "PmListWithStripeForIdeal" ]; diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js index a36b4ae1d187..ae72465b6065 100644 --- a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js +++ b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js @@ -1,13 +1,4 @@ -import State from "../../utils/State"; - -const globalState = new State({ - connectorId: Cypress.env("CONNECTOR"), - baseUrl: Cypress.env("BASEURL"), - adminApiKey: Cypress.env("ADMINAPIKEY"), - connectorAuthFilePath: Cypress.env("CONNECTOR_AUTH_FILE_PATH"), -}); - -export const card_credit_enabled = [ +export const cardCreditEnabled = [ { payment_method: "card", payment_method_types: [ @@ -15,6 +6,10 @@ export const card_credit_enabled = [ payment_method_type: "credit", card_networks: ["Visa"], minimum_amount: 0, + accepted_currencies: { + type: "enable_only", + list: ["USD"], + }, maximum_amount: 68607706, recurring_enabled: false, installment_payment_enabled: true, @@ -23,7 +18,7 @@ export const card_credit_enabled = [ }, ]; -export const card_credit_enabled_in_USD = [ +export const cardCreditEnabledInUsd = [ { payment_method: "card", payment_method_types: [ @@ -43,7 +38,7 @@ export const card_credit_enabled_in_USD = [ }, ]; -export const card_credit_enabled_in_US = [ +export const cardCreditEnabledInUs = [ { payment_method: "card", payment_method_types: [ @@ -63,7 +58,7 @@ export const card_credit_enabled_in_US = [ }, ]; -export const bank_redirect_ideal_enabled = [ +export const bankRedirectIdealEnabled = [ { payment_method: "bank_redirect", payment_method_types: [ @@ -81,7 +76,7 @@ export const bank_redirect_ideal_enabled = [ }, ]; -export const bank_redirect_ideal_and_credit_enabled = [ +export const bankRedirectIdealAndCreditEnabled = [ { payment_method: "card", payment_method_types: [ @@ -112,7 +107,7 @@ export const bank_redirect_ideal_and_credit_enabled = [ }, ]; -export const create_payment_body_with_currency_country = ( +export const createPaymentBodyWithCurrencyCountry = ( currency, billingCountry, shippingCountry @@ -167,7 +162,7 @@ export const create_payment_body_with_currency_country = ( }, }); -export const create_payment_body_with_currency = (currency) => ({ +export const createPaymentBodyWithCurrency = (currency) => ({ currency: currency, amount: 6500, authentication_type: "three_ds", diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Stripe.js b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Stripe.js index 32d138fdc1f2..aee9aa0f5361 100644 --- a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Stripe.js +++ b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Stripe.js @@ -1,11 +1,3 @@ -const successfulNo3DSCardDetails = { - card_number: "4242424242424242", - card_exp_month: "10", - card_exp_year: "50", - card_holder_name: "morino", - card_cvc: "737", -}; - export const connectorDetails = { pm_list: { PaymentIntent: { diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js index 9a1d35583c42..f7d199164fd4 100644 --- a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js +++ b/cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js @@ -7,7 +7,7 @@ const connectorDetails = { }; export default function getConnectorDetails(connectorId) { - let x = mergeDetails(connectorId); + const x = mergeDetails(connectorId); return x; } @@ -28,11 +28,11 @@ function getValueByKey(jsonObject, key) { } } -export const should_continue_further = (res_data) => { +export const should_continue_further = (resData) => { if ( - res_data.body.error !== undefined || - res_data.body.error_code !== undefined || - res_data.body.error_message !== undefined + typeof resData.body.error !== "undefined" || + typeof resData.body.error_code !== "undefined" || + typeof resData.body.error_message !== "undefined" ) { return false; } else { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js index 5753421a7458..1788a369faf6 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js @@ -1,5 +1,5 @@ -import State from "../../utils/State"; import * as fixtures from "../../fixtures/imports"; +import State from "../../utils/State"; let globalState; describe("Account Create flow test", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js index 7a8b7b633024..9c9e757598b3 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js @@ -22,4 +22,32 @@ describe("Connector Account Create flow test", () => { globalState ); }); + + it("check and create multiple connectors", () => { + const multiple_connectors = Cypress.env("MULTIPLE_CONNECTORS"); + // multiple_connectors will be undefined if not set in the env + if (multiple_connectors?.status) { + // Create multiple connectors based on the count + // The first connector is already created when creating merchant account, so start from 1 + for (let i = 1; i < multiple_connectors.count; i++) { + cy.createBusinessProfileTest( + fixtures.businessProfile.bpCreate, + globalState, + "profile" + i + ); + cy.createConnectorCallTest( + "payment_processor", + fixtures.createConnectorBody, + payment_methods_enabled, + globalState, + `profile${i}`, + `merchantConnector${i}` + ); + } + } else { + cy.log( + "Multiple connectors not enabled. Skipping creation of multiple profiles and respective MCAs" + ); + } + }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js index e8c719cebc74..62f4af2338c3 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js @@ -16,30 +16,28 @@ describe("Card - NoThreeDS payment flow test", () => { }); context("Card-NoThreeDS payment flow test Create and confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -47,57 +45,55 @@ describe("Card - NoThreeDS payment flow test", () => { }); it("Confirm No 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); context("Card-NoThreeDS payment flow test Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js index 91dc2b1c382c..3a0b635f79a2 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js @@ -5,10 +5,10 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("Card - ThreeDS payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -24,21 +24,19 @@ describe("Card - ThreeDS payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -46,24 +44,17 @@ describe("Card - ThreeDS payment flow test", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "3DSAutoCapture" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js index 6a74e6fb910a..d9769daab4b6 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js @@ -17,30 +17,29 @@ describe("Card - NoThreeDS Manual payment flow test", () => { context("Card - NoThreeDS Manual Full Capture payment flow test", () => { context("payment Create and Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -48,104 +47,95 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); context("Payment Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); }); @@ -154,30 +144,29 @@ describe("Card - NoThreeDS Manual payment flow test", () => { "Card - NoThreeDS Manual Partial Capture payment flow test - Create and Confirm", () => { context("payment Create and Payment Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -185,103 +174,95 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); context("payment + Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); } diff --git a/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js index 2b1295fd07cc..0050aa39bfc1 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js @@ -16,30 +16,28 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); context("Card - void payment in Requires_capture state flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -47,63 +45,52 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("void-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "VoidAfterConfirm" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["VoidAfterConfirm"]; + + cy.voidCallTest(fixtures.voidBody, data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context( "Card - void payment in Requires_payment_method state flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -111,43 +98,41 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); it("void-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Void"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.voidCallTest(fixtures.voidBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); context("Card - void payment in success state flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -155,33 +140,23 @@ describe("Card - NoThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - false, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, false, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("void-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "VoidAfterConfirm" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["VoidAfterConfirm"]; + + cy.voidCallTest(fixtures.voidBody, data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js index 95d86a62278a..370d811ed628 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js @@ -5,10 +5,10 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("Card - Sync payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -23,21 +23,19 @@ describe("Card - Sync payment flow test", () => { cy.task("setGlobalState", globalState.data); }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -45,25 +43,19 @@ describe("Card - Sync payment flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "No3DSAutoCapture" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + "No3DSAutoCapture" + ]; + cy.retrievePaymentCallTest(globalState, data); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js index 4eef1ac87371..4d534127ada2 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js @@ -16,30 +16,28 @@ describe("Card - Refund flow - No 3DS", () => { }); context("Card - Full Refund flow test for No-3DS", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -47,82 +45,67 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Refund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Refund"]; + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - Partial Refund flow test for No-3DS", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -130,134 +113,110 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 1200, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 1200, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 1200, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 1200, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context( "Fully Refund Card-NoThreeDS payment flow test Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Refund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SyncRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -265,109 +224,97 @@ describe("Card - Refund flow - No 3DS", () => { context( "Partially Refund Card-NoThreeDS payment flow test Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SyncRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); context("Card - Full Refund for fully captured No-3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -375,104 +322,85 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Capture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - Partial Refund for fully captured No-3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -480,92 +408,68 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Capture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentPartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentPartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentPartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentPartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("list-refund-call-test", () => { cy.listRefundCallTest(fixtures.listRefundCall, globalState); @@ -573,30 +477,28 @@ describe("Card - Refund flow - No 3DS", () => { }); context("Card - Full Refund for partially captured No-3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -604,104 +506,85 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - partial Refund for partially captured No-3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -709,121 +592,100 @@ describe("Card - Refund flow - No 3DS", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentPartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentPartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context( "Card - Full Refund for Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateMultiUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + req_data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -832,15 +694,13 @@ describe("Card - Refund flow - No 3DS", () => { }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -849,31 +709,25 @@ describe("Card - Refund flow - No 3DS", () => { }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Refund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 7000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 7000, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SyncRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -891,30 +745,28 @@ describe("Card - Refund flow - 3DS", () => { }); context("Card - Full Refund flow test for 3DS", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -922,85 +774,72 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Refund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Refund"]; + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - Partial Refund flow test for 3DS", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -1008,253 +847,217 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 1200, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 1200, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 1200, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 1200, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Fully Refund Card-ThreeDS payment flow test Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Refund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Refund"]; + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context( "Partially Refund Card-ThreeDS payment flow test Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 3000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 3000, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SyncRefund"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); context("Card - Full Refund for fully captured 3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -1262,107 +1065,90 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Capture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - Partial Refund for fully captured 3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -1370,123 +1156,99 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Capture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentPartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 5000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentPartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 5000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentPartialRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 1500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentPartialRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 1500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - Full Refund for partially captured 3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -1494,107 +1256,90 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("Card - partial Refund for partially captured 3DS payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -1602,79 +1347,64 @@ describe("Card - Refund flow - 3DS", () => { }); it("Confirm 3DS", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PartialCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "manualPaymentRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 50, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["manualPaymentRefund"]; + + cy.refundCallTest(fixtures.refundBody, data, 50, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SyncRefund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SyncRefund"]; + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js index 617a0e721b94..dc7386211666 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js @@ -5,10 +5,10 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("Card - Sync Refund flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -24,21 +24,19 @@ describe("Card - Sync Refund flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -46,53 +44,40 @@ describe("Card - Sync Refund flow test", () => { }); it("confirm-call-test", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "No3DSAutoCapture" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + "No3DSAutoCapture" + ]; + + cy.retrievePaymentCallTest(globalState, data); }); it("refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "Refund" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("sync-refund-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ + const data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ "SyncRefund" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.syncRefundCallTest(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.syncRefundCallTest(data, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js index bace2a780183..da2123d64623 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js @@ -18,46 +18,41 @@ describe("Card - SingleUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateSingleUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -70,64 +65,52 @@ describe("Card - SingleUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateSingleUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -136,21 +119,14 @@ describe("Card - SingleUse Mandates flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("list-mandate-call-test", () => { @@ -162,64 +138,52 @@ describe("Card - SingleUse Mandates flow test", () => { context( "Card - No threeDS Create + Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateSingleUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js index 312c74c23c08..000d69c45e68 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js @@ -18,46 +18,41 @@ describe("Card - MultiUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateMultiUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -65,15 +60,13 @@ describe("Card - MultiUse Mandates flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -86,64 +79,52 @@ describe("Card - MultiUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateMultiUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT 1", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -152,33 +133,24 @@ describe("Card - MultiUse Mandates flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT 2", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -187,21 +159,14 @@ describe("Card - MultiUse Mandates flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -209,64 +174,52 @@ describe("Card - MultiUse Mandates flow test", () => { context( "Card - ThreeDS Create + Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateMultiUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 6500, true, "automatic", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js index cad829ba3107..b8d0a51879de 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js @@ -18,46 +18,41 @@ describe("Card - List and revoke Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MandateSingleUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -79,32 +74,30 @@ describe("Card - List and revoke Mandates flow test", () => { } ); context("Card - Zero auth CIT and MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "ZeroAuthMandate" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["ZeroAuthMandate"]; + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 0, true, "automatic", "setup_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("list-mandate-call-test", () => { @@ -112,15 +105,13 @@ describe("Card - List and revoke Mandates flow test", () => { }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "MITAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["MITAutoCapture"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js index ae8e276c8d4c..bab24076f550 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js @@ -19,11 +19,11 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS automatic capture payment- Create+Confirm [on_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -33,26 +33,29 @@ describe("Card - SaveCard payment flow test", () => { }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) { - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) { + shouldContinue = utils.should_continue_further(data); } }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("retrieve-customerPM-call-test", () => { @@ -60,37 +63,31 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -98,11 +95,11 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS manual full capture payment- Create+Confirm [on_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -112,25 +109,28 @@ describe("Card - SaveCard payment flow test", () => { }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("retrieve-customerPM-call-test", () => { @@ -138,58 +138,50 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -197,11 +189,11 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS manual partial capture payment- Create + Confirm [on_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -211,25 +203,28 @@ describe("Card - SaveCard payment flow test", () => { }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("retrieve-customerPM-call-test", () => { @@ -237,57 +232,49 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 100, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -295,11 +282,11 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS automatic capture payment [off_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -309,25 +296,28 @@ describe("Card - SaveCard payment flow test", () => { }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCaptureOffSession"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("retrieve-customerPM-call-test", () => { @@ -335,38 +325,31 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardConfirmAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -374,10 +357,10 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS manual capture payment- Create+Confirm [off_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); @@ -388,41 +371,38 @@ describe("Card - SaveCard payment flow test", () => { }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSManualCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSManualCaptureOffSession"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-customerPM-call-test", () => { @@ -430,62 +410,58 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardConfirmManualCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardConfirmManualCaptureOffSession"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); } ); @@ -493,11 +469,11 @@ describe("Card - SaveCard payment flow test", () => { context( "Save card for NoThreeDS automatic capture payment - create and confirm [off_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -507,42 +483,39 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCaptureOffSession"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("retrieve-customerPM-call-test", () => { @@ -550,49 +523,42 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardConfirmAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); context( "Use billing address from payment method during subsequent payment[off_session]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { saveCardBody = Cypress._.cloneDeep(fixtures.saveCardConfirmBody); - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -602,38 +568,31 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-customerPM-call-test", () => { @@ -641,38 +600,31 @@ describe("Card - SaveCard payment flow test", () => { }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("confirm-save-card-payment-call-test-without-billing", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardConfirmAutoCaptureOffSessionWithoutBilling"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.saveCardConfirmCallTest( - saveCardBody, - req_data, - res_data, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.saveCardConfirmCallTest(saveCardBody, data, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js index 15e7597286a3..0cc1be503189 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js @@ -18,44 +18,41 @@ describe("Card - SingleUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and Single use MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["ZeroAuthMandate"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 0, true, "automatic", "setup_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -67,44 +64,41 @@ describe("Card - SingleUse Mandates flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and Multi use MIT payment flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["ZeroAuthMandate"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 0, true, "automatic", "setup_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -112,15 +106,13 @@ describe("Card - SingleUse Mandates flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -131,51 +123,46 @@ describe("Card - SingleUse Mandates flow test", () => { ); context("Card - Zero Auth Payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create No 3DS Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "ZeroAuthPaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["ZeroAuthPaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "ZeroAuthConfirmPayment" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["ZeroAuthConfirmPayment"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve Payment Call Test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["ZeroAuthConfirmPayment"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Retrieve CustomerPM Call Test", () => { @@ -183,38 +170,33 @@ describe("Card - SingleUse Mandates flow test", () => { }); it("Create Recurring Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntentOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Confirm Recurring Payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SaveCardConfirmAutoCaptureOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardConfirmAutoCaptureOffSession"]; cy.saveCardConfirmCallTest( fixtures.saveCardConfirmBody, - req_data, - res_data, + data, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js index 3d236af7a910..0426d17013ce 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js @@ -6,14 +6,6 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("Card - ThreeDS Manual payment flow test", () => { - let should_continue = true; - - beforeEach(function () { - if (!should_continue) { - this.skip(); - } - }); - before("seed global state", () => { cy.task("getGlobalState").then((state) => { globalState = new State(state); @@ -26,30 +18,29 @@ describe("Card - ThreeDS Manual payment flow test", () => { context("Card - ThreeDS Manual Full Capture payment flow test", () => { context("payment Create and Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -57,97 +48,106 @@ describe("Card - ThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest(captureBody, req_data, res_data, 6500, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); context("Payment Create+Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = + const expected_redirection = fixtures.createConfirmPaymentBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest(captureBody, req_data, res_data, 6500, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); }); @@ -156,30 +156,29 @@ describe("Card - ThreeDS Manual payment flow test", () => { "Card - ThreeDS Manual Partial Capture payment flow test - Create and Confirm", () => { context("payment Create and Payment Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -187,97 +186,106 @@ describe("Card - ThreeDS Manual payment flow test", () => { }); it("confirm-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest(captureBody, req_data, res_data, 100, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(captureBody, data, 100, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); context("payment + Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create+confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = + const expected_redirection = fixtures.createConfirmPaymentBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PartialCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest(captureBody, req_data, res_data, 100, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(captureBody, data, 100, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PartialCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); } diff --git a/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js index ee83f1aa4485..913dd91ea8be 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js @@ -16,30 +16,28 @@ describe("Bank Transfers", () => { }); context("Bank transfer - Pix forward flow", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -47,25 +45,24 @@ describe("Bank Transfers", () => { }); it("Confirm bank transfer", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["Pix"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankTransferCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle bank transfer redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankTransferRedirection( globalState, payment_method_type, diff --git a/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js index f3c81c16ab2d..cc3b8dbaec76 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js @@ -10,7 +10,7 @@ describe("Bank Redirect tests", () => { }); context("Blik Create and Confirm flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -19,27 +19,24 @@ describe("Bank Redirect tests", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["BlikPaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -47,25 +44,23 @@ describe("Bank Redirect tests", () => { }); it("Confirm bank redirect", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["Blik"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("EPS Create and Confirm flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -74,27 +69,24 @@ describe("Bank Redirect tests", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -102,26 +94,25 @@ describe("Bank Redirect tests", () => { }); it("Confirm bank redirect", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["Eps"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankRedirectRedirection( globalState, payment_method_type, @@ -131,7 +122,7 @@ describe("Bank Redirect tests", () => { }); context("iDEAL Create and Confirm flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -140,27 +131,24 @@ describe("Bank Redirect tests", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -168,26 +156,24 @@ describe("Bank Redirect tests", () => { }); it("Confirm bank redirect", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["Ideal"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, @@ -197,7 +183,7 @@ describe("Bank Redirect tests", () => { }); context("Sofort Create and Confirm flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -206,26 +192,23 @@ describe("Bank Redirect tests", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -233,26 +216,24 @@ describe("Bank Redirect tests", () => { }); it("Confirm bank redirect", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["Sofort"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, @@ -262,7 +243,7 @@ describe("Bank Redirect tests", () => { }); context("Przelewy24 Create and Confirm flow test", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -271,26 +252,23 @@ describe("Bank Redirect tests", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -298,25 +276,23 @@ describe("Bank Redirect tests", () => { }); it("Confirm bank redirect", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "bank_redirect_pm" ]["Przelewy24"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle bank redirect redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, diff --git a/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js index 401f662c67e2..1a2dff1b5da3 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js @@ -18,64 +18,58 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create No 3DS Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandateNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -88,82 +82,69 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create No 3DS Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandateNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -176,46 +157,41 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - NoThreeDS Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandateNo3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -223,15 +199,13 @@ describe("Card - Mandates using Payment Method Id flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -244,64 +218,52 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - NoThreeDS Create + Confirm Manual CIT and MIT payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm No 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandateNo3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT 1", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -310,33 +272,24 @@ describe("Card - Mandates using Payment Method Id flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT 2", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -345,21 +298,14 @@ describe("Card - Mandates using Payment Method Id flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -367,51 +313,46 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - ThreeDS Create + Confirm Automatic CIT and MIT payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandate3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.citConfirmBody["return_url"]; + const expected_redirection = fixtures.citConfirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -419,15 +360,13 @@ describe("Card - Mandates using Payment Method Id flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -440,69 +379,57 @@ describe("Card - Mandates using Payment Method Id flow test", () => { context( "Card - ThreeDS Create + Confirm Manual CIT and MIT payment flow", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Confirm 3DS CIT", () => { - console.log("confirm -> " + globalState.get("connectorId")); - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentMethodIdMandate3DSManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.citConfirmBody["return_url"]; + const expected_redirection = fixtures.citConfirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - console.log("det -> " + data.card); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingPMId( fixtures.pmIdConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTID.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTID.cy.js index dcccfd390bf1..e3080d39878e 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTID.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTID.cy.js @@ -20,24 +20,20 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Automatic MIT payment flow test", () => { - let should_continue = true; - beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -50,24 +46,20 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Manual MIT payment flow test", () => { - let should_continue = true; - beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "manual", @@ -80,24 +72,20 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Automatic multiple MITs payment flow test", () => { - let should_continue = true; - beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -105,15 +93,13 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -126,24 +112,22 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - NoThreeDS Create and Confirm Manual multiple MITs payment flow test", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT 1", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -152,33 +136,24 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm No 3DS MIT 2", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITManualCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", @@ -187,21 +162,14 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { }); it("mit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Capture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); } ); @@ -209,24 +177,20 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - ThreeDS Create and Confirm Automatic multiple MITs payment flow test", () => { - let should_continue = true; - beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -234,15 +198,13 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { ); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", @@ -255,24 +217,20 @@ describe("Card - Mandates using Network Transaction Id flow test", () => { context( "Card - ThreeDS Create and Confirm Manual multiple MITs payment flow", () => { - let should_continue = true; - beforeEach(function () { - if (!should_continue || connector !== "cybersource") { + if (connector !== "cybersource") { this.skip(); } }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["MITAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.mitUsingNTID( fixtures.ntidConfirmBody, - req_data, - res_data, + data, 7000, true, "automatic", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js index 72c99d2d19d1..e7a06c622489 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js @@ -5,7 +5,7 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("UPI Payments - Hyperswitch", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails context("[Payment] [UPI - UPI Collect] Create & Confirm + Refund", () => { before("seed global state", () => { @@ -19,29 +19,25 @@ describe("UPI Payments - Hyperswitch", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["upi_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["PaymentIntent"]; cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("List Merchant payment methods", () => { @@ -49,27 +45,19 @@ describe("UPI Payments - Hyperswitch", () => { }); it("Confirm payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["upi_pm"][ - "UpiCollect" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - cy.confirmUpiCall( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["UpiCollect"]; - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.confirmUpiCall(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle UPI Redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); + cy.handleUpiRedirection( globalState, payment_method_type, @@ -78,31 +66,27 @@ describe("UPI Payments - Hyperswitch", () => { }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["UpiCollect"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Refund payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["upi_pm"][ - "Refund" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 6500, - globalState - ); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["Refund"]; - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.refundCallTest(fixtures.refundBody, data, 6500, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); // Skipping UPI Intent intentionally as connector is throwing 5xx during redirection context.skip("[Payment] [UPI - UPI Intent] Create & Confirm", () => { - should_continue = true; // variable that will be used to skip tests if a previous test fails + shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -115,29 +99,25 @@ describe("UPI Payments - Hyperswitch", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["upi_pm"][ - "PaymentIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["PaymentIntent"]; cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("List Merchant payment methods", () => { @@ -145,27 +125,19 @@ describe("UPI Payments - Hyperswitch", () => { }); it("Confirm payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["upi_pm"][ - "UpiIntent" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - cy.confirmUpiCall( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["UpiIntent"]; - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.confirmUpiCall(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Handle UPI Redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); + cy.handleUpiRedirection( globalState, payment_method_type, @@ -174,7 +146,11 @@ describe("UPI Payments - Hyperswitch", () => { }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "upi_pm" + ]["UpiIntent"]; + + cy.retrievePaymentCallTest(globalState, data); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js index 035b7da97abc..b3c220bc178b 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js @@ -27,16 +27,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid card number", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidCardNumber" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -44,16 +41,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid expiry month", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidExpiryMonth" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -61,16 +55,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid expiry year", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidExpiryYear" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -78,16 +69,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid card CVV", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidCardCvv" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -95,16 +83,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid currency", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidCurrency" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -112,16 +97,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid capture method", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidCaptureMethod" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -129,16 +111,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid payment method", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidPaymentMethod" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -146,16 +125,13 @@ describe("Corner cases", () => { }); it("[Payment] Invalid `amount_to_capture`", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "InvalidAmountToCapture" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -163,16 +139,13 @@ describe("Corner cases", () => { }); it("[Payment] Missing required params", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "MissingRequiredParam" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPaymentTest( paymentIntentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -192,16 +165,13 @@ describe("Corner cases", () => { }); it("Create payment intent", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createPaymentIntentTest( paymentIntentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -209,24 +179,16 @@ describe("Corner cases", () => { }); it("Confirm payment intent", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "PaymentIntentErrored" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); }); context("[Payment] Capture greater amount", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -239,55 +201,40 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSManualCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSManualCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Capture call", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "CaptureGreaterAmount" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 65000, - globalState - ); + cy.captureCallTest(fixtures.captureBody, data, 65000, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Capture successful payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -300,59 +247,48 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Capture call", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "CaptureCapturedAmount" - ]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["CaptureCapturedAmount"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.captureCallTest(fixtures.captureBody, data, 65000, globalState); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 65000, - globalState - ); - - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Confirm successful payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -365,58 +301,48 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Confirm call", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "ConfirmSuccessfulPayment" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["ConfirmSuccessfulPayment"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Void successful payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -429,58 +355,60 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Void call", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Void" - ]; - let commonData = getConnectorDetails(globalState.get("commons"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Void"]; - let req_data = data["Request"]; - let res_data = utils.getConnectorFlowDetails( - data, - commonData, - "ResponseCustom" - ); - cy.voidCallTest(fixtures.voidBody, req_data, res_data, globalState); + const commonData = getConnectorDetails(globalState.get("commons"))[ + "card_pm" + ]["Void"]; + + const newData = { + ...data, + Response: utils.getConnectorFlowDetails( + data, + commonData, + "ResponseCustom" + ), + }; - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.voidCallTest(fixtures.voidBody, newData, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] 3DS with greater capture", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -493,68 +421,61 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "3DSManualCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "three_ds", "manual", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Handle redirection", () => { - let expected_redirection = fixtures.confirmBody["return_url"]; + const expected_redirection = fixtures.confirmBody["return_url"]; cy.handleRedirection(globalState, expected_redirection); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["3DSManualCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Capture call", () => { - let data = getConnectorDetails(globalState.get("commons"))["card_pm"][ + const data = getConnectorDetails(globalState.get("commons"))["card_pm"][ "CaptureGreaterAmount" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.captureCallTest(fixtures.captureBody, data, 65000, globalState); - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 65000, - globalState - ); - - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Refund exceeds captured Amount", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -567,63 +488,59 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Refund call", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Refund" - ]; - let commonData = getConnectorDetails(globalState.get("commons"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Refund"]; - let req_data = data["Request"]; - let res_data = utils.getConnectorFlowDetails( - data, - commonData, - "ResponseCustom" - ); - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 65000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const commonData = getConnectorDetails(globalState.get("commons"))[ + "card_pm" + ]["Refund"]; + + const newData = { + ...data, + Response: utils.getConnectorFlowDetails( + data, + commonData, + "ResponseCustom" + ), + }; + + cy.refundCallTest(fixtures.refundBody, newData, 65000, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Refund unsuccessful payment", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -636,63 +553,60 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("Create payment intent and confirm", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "No3DSAutoCapture" - ]; - - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; cy.createConfirmPaymentTest( paymentCreateConfirmBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["No3DSAutoCapture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Refund call", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Refund" - ]; - let commonData = getConnectorDetails(globalState.get("commons"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Refund"]; - let req_data = data["Request"]; - let res_data = utils.getConnectorFlowDetails( - data, - commonData, - "ResponseCustom" - ); - cy.refundCallTest( - fixtures.refundBody, - req_data, - res_data, - 65000, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const commonData = getConnectorDetails(globalState.get("commons"))[ + "card_pm" + ]["Refund"]; + + const newData = { + ...data, + Response: utils.getConnectorFlowDetails( + data, + commonData, + "ResponseCustom" + ), + }; + + cy.refundCallTest(fixtures.refundBody, newData, 65000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); }); context("[Payment] Recurring mandate with greater mandate amount", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -705,62 +619,53 @@ describe("Corner cases", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("No 3DS CIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "MandateSingleUseNo3DSManualCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["MandateSingleUseNo3DSManualCapture"]; + cy.citForMandatesCallTest( fixtures.citConfirmBody, - req_data, - res_data, + data, 6500, true, "manual", "new_mandate", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("cit-capture-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "Capture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.captureCallTest( - fixtures.captureBody, - req_data, - res_data, - 6500, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Retrieve payment", () => { - cy.retrievePaymentCallTest(globalState); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.retrievePaymentCallTest(globalState, data); }); it("Confirm No 3DS MIT", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "MITAutoCapture" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["MITAutoCapture"]; + cy.mitForMandatesCallTest( fixtures.mitConfirmBody, - req_data, - res_data, + data, 65000, true, "manual", diff --git a/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js index c27604a07d6c..9dc73f6223e6 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js @@ -5,8 +5,6 @@ import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; let globalState; describe("Payment Methods Tests", () => { - let should_continue = true; - before("seed global state", () => { cy.task("getGlobalState").then((state) => { globalState = new State(state); @@ -18,23 +16,14 @@ describe("Payment Methods Tests", () => { }); context("Create payment method for customer", () => { - let should_continue = true; - - beforeEach(function () { - if (!should_continue) { - this.skip(); - } - }); - it("Create customer", () => { cy.createCustomerCallTest(fixtures.customerCreateBody, globalState); }); it("Create Payment Method", () => { - let data = getConnectorDetails("commons")["card_pm"]["PaymentMethod"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentMethodTest(globalState, req_data, res_data); + const data = getConnectorDetails("commons")["card_pm"]["PaymentMethod"]; + + cy.createPaymentMethodTest(globalState, data); }); it("List PM for customer", () => { @@ -43,10 +32,10 @@ describe("Payment Methods Tests", () => { }); context("Set default payment method", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -56,45 +45,33 @@ describe("Payment Methods Tests", () => { }); it("Create Payment Method", () => { - let data = getConnectorDetails("commons")["card_pm"]["PaymentMethod"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentMethodTest(globalState, req_data, res_data); + const data = getConnectorDetails("commons")["card_pm"]["PaymentMethod"]; + + cy.createPaymentMethodTest(globalState, data); }); it("create-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntentOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("confirm-payment-call-test", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SaveCardUseNo3DSAutoCaptureOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCaptureOffSession"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("List PM for customer", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnostic.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnostic.cy.js index 29b0097253df..c5fddfdd5bf1 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnostic.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnostic.cy.js @@ -2,7 +2,9 @@ import * as fixtures from "../../fixtures/imports"; import State from "../../utils/State"; import { payment_methods_enabled } from "../PaymentUtils/Commons"; import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; + let globalState; + describe("Connector Agnostic Tests", () => { before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -16,10 +18,10 @@ describe("Connector Agnostic Tests", () => { context( "Connector Agnostic Disabled for Profile 1 and Enabled for Profile 2", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -45,38 +47,31 @@ describe("Connector Agnostic Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("Confirm Payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SaveCardUseNo3DSAutoCaptureOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("List Payment Method for Customer using Client Secret", () => { @@ -112,21 +107,20 @@ describe("Connector Agnostic Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("List Payment Method for Customer", () => { @@ -136,10 +130,10 @@ describe("Connector Agnostic Tests", () => { ); context("Connector Agnostic Enabled for Profile 1 and Profile 2", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -177,38 +171,29 @@ describe("Connector Agnostic Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntentOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("Confirm Payment", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "SaveCardUseNo3DSAutoCaptureOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSAutoCaptureOffSession"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("List Payment Method for Customer using Client Secret", () => { @@ -244,21 +229,19 @@ describe("Connector Agnostic Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))["card_pm"][ - "PaymentIntentOffSession" - ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("List Payment Method for Customer", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00025-ConfigTest.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00025-ConfigTest.cy.js index 724233852c78..b1ccc55ccb34 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00025-ConfigTest.cy.js +++ b/cypress-tests/cypress/e2e/PaymentTest/00025-ConfigTest.cy.js @@ -19,10 +19,10 @@ describe("Config Tests", () => { context( "Update collect_billing_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -60,24 +60,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -89,10 +85,10 @@ describe("Config Tests", () => { context( "Update collect_shipping_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -110,24 +106,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -139,10 +131,10 @@ describe("Config Tests", () => { context( "Update always_collect_billing_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -160,24 +152,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -189,10 +177,10 @@ describe("Config Tests", () => { context( "Update always_collect_shipping_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -210,24 +198,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -239,10 +223,10 @@ describe("Config Tests", () => { context( "Update always_collect_shipping_details_from_wallet_connector & collect_shipping_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -260,24 +244,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -288,10 +268,10 @@ describe("Config Tests", () => { context( "Update always_collect_billing_details_from_wallet_connector & to collect_billing_details_from_wallet_connector to true and verifying in payment method list, this config should be true", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -309,24 +289,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { @@ -338,10 +314,10 @@ describe("Config Tests", () => { context( "Update all config(Collect address config) to false and verifying in payment method list, both config should be false", () => { - let should_continue = true; + let shouldContinue = true; beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -379,24 +355,20 @@ describe("Config Tests", () => { }); it("Create Payment Intent", () => { - let data = getConnectorDetails(globalState.get("connectorId"))[ + const data = getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["PaymentIntentOffSession"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("payment_methods-call-test", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js new file mode 100644 index 000000000000..a325ac5f2f0d --- /dev/null +++ b/cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js @@ -0,0 +1,175 @@ +import * as fixtures from "../../fixtures/imports"; +import State from "../../utils/State"; +import { cardCreditEnabled } from "../PaymentMethodListUtils/Commons"; +import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; + +let globalState; + +describe("Dynamic Fields Verification", () => { + context("Verify the Dynamic fields for card", () => { + before("seed global state", () => { + cy.task("getGlobalState").then((state) => { + globalState = new State(state); + }); + }); + + after("flush global state", () => { + cy.task("setGlobalState", globalState.data); + }); + + context( + "Verify the Dynamic fields - Payment without billing address", + () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue) { + this.skip(); + } + }); + + it("Create Business Profile", () => { + cy.createBusinessProfileTest( + fixtures.businessProfile.bpCreate, + globalState + ); + }); + + it("connector-create-call-test", () => { + cy.createConnectorCallTest( + "payment_processor", + fixtures.createConnectorBody, + cardCreditEnabled, + globalState + ); + }); + + it("Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentWithoutBilling"]; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + data, + "no_three_ds", + "automatic", + globalState + ); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); + }); + + it("Payment Method List", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "pm_list" + ]["PmListResponse"]["pmListDynamicFieldWithoutBilling"]; + cy.paymentMethodListTestWithRequiredFields(data, globalState); + }); + } + ); + + context("Verify the Dynamic fields - Payment with billing address", () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue) { + this.skip(); + } + }); + + it("Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentWithBilling"]; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + data, + "no_three_ds", + "automatic", + globalState + ); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); + }); + + it("Payment Method List", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "pm_list" + ]["PmListResponse"]["pmListDynamicFieldWithBilling"]; + cy.paymentMethodListTestWithRequiredFields(data, globalState); + }); + }); + + context( + "Verify the Dynamic fields - Payment with billing First and Last name", + () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue) { + this.skip(); + } + }); + + it("Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentWithFullName"]; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + data, + "no_three_ds", + "automatic", + globalState + ); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); + }); + + it("Payment Method List", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "pm_list" + ]["PmListResponse"]["pmListDynamicFieldWithNames"]; + cy.paymentMethodListTestWithRequiredFields(data, globalState); + }); + } + ); + + context("Verify the Dynamic fields - Payment with billing Email", () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue) { + this.skip(); + } + }); + + it("Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentWithBillingEmail"]; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + data, + "no_three_ds", + "automatic", + globalState + ); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); + }); + + it("Payment Method List", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "pm_list" + ]["PmListResponse"]["pmListDynamicFieldWithEmail"]; + cy.paymentMethodListTestWithRequiredFields(data, globalState); + }); + }); + }); +}); +1; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js b/cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js new file mode 100644 index 000000000000..e281fc0a2f7a --- /dev/null +++ b/cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js @@ -0,0 +1,139 @@ +import * as fixtures from "../../fixtures/imports"; +import State from "../../utils/State"; +import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; + +let connector; +let globalState; + +describe.skip("[Payment] Incremental Auth", () => { + before("seed global state", () => { + cy.task("getGlobalState").then((state) => { + globalState = new State(state); + connector = globalState.get("connectorId"); + }); + }); + + after("flush global state", () => { + cy.task("setGlobalState", globalState.data); + }); + + context("[Payment] Incremental Pre-Auth", () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue || connector !== "cybersource") { + this.skip(); + } + }); + + it("[Payment] Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + + const newData = { + ...data, + Request: { + ...data.Request, + request_incremental_authorization: true, + }, + }; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + newData, + "no_three_ds", + "manual", + globalState + ); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Confirm Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSManualCaptureOffSession"]; + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Incremental Authorization", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["IncrementalAuth"]; + cy.incrementalAuth(globalState, data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Capture Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 7000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + }); + + context("[Payment] [Saved Card] Incremental Pre-Auth", () => { + let shouldContinue = true; + + beforeEach(function () { + if (!shouldContinue || connector !== "cybersource") { + this.skip(); + } + }); + + it("[Payment] List customer payment methods", () => { + cy.listCustomerPMCallTest(globalState); + }); + it("[Payment] Create Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["PaymentIntentOffSession"]; + + cy.createPaymentIntentTest( + fixtures.createPaymentBody, + data, + "no_three_ds", + "manual", + globalState + ); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Confirm Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["SaveCardUseNo3DSManualCaptureOffSession"]; + + cy.saveCardConfirmCallTest( + fixtures.saveCardConfirmBody, + data, + globalState + ); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Incremental Authorization", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["IncrementalAuth"]; + + cy.incrementalAuth(globalState, data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + it("[Payment] Capture Payment Intent", () => { + const data = getConnectorDetails(globalState.get("connectorId"))[ + "card_pm" + ]["Capture"]; + + cy.captureCallTest(fixtures.captureBody, data, 7000, globalState); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); + }); + }); +}); diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js b/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js index 81525041147d..db3206e5dde5 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js @@ -982,4 +982,215 @@ export const connectorDetails = { }, }, }, + pm_list: { + PmListResponse: { + PmListNull: { + payment_methods: [], + }, + pmListDynamicFieldWithoutBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["adyen"], + }, + ], + required_fields: { + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["adyen"], + }, + ], + required_fields: { + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithNames: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["adyen"], + }, + ], + required_fields: { + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithEmail: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["adyen"], + }, + ], + required_fields: { + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + }, + }, + ], + }, + ], + }, + }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js b/cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js index 6f383367e057..a5af06b908a2 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js @@ -675,4 +675,265 @@ export const connectorDetails = { }, }, }, + pm_list: { + PmListResponse: { + PmListNull: { + payment_methods: [], + }, + pmListDynamicFieldWithoutBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["bankofamerica"], + }, + ], + required_fields: { + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + "billing.address.state": { + required_field: "payment_method_data.billing.address.state", + display_name: "state", + field_type: "user_address_state", + value: null, + }, + "billing.address.country": { + required_field: + "payment_method_data.billing.address.country", + display_name: "country", + field_type: { + user_address_country: { + options: ["ALL"], + }, + }, + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "billing.address.zip": { + required_field: "payment_method_data.billing.address.zip", + display_name: "zip", + field_type: "user_address_pincode", + value: null, + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "billing.address.line1": { + required_field: "payment_method_data.billing.address.line1", + display_name: "line1", + field_type: "user_address_line1", + value: null, + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + email: { + required_field: "email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch_sdk_demo_id@gmail.com", + }, + "billing.address.city": { + required_field: "payment_method_data.billing.address.city", + display_name: "city", + field_type: "user_address_city", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["bankofamerica"], + }, + ], + required_fields: { + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + "billing.address.state": { + required_field: "payment_method_data.billing.address.state", + display_name: "state", + field_type: "user_address_state", + value: "CA", + }, + "billing.address.country": { + required_field: + "payment_method_data.billing.address.country", + display_name: "country", + field_type: { + user_address_country: { + options: ["ALL"], + }, + }, + value: "PL", + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "billing.address.zip": { + required_field: "payment_method_data.billing.address.zip", + display_name: "zip", + field_type: "user_address_pincode", + value: "94122", + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "billing.address.line1": { + required_field: "payment_method_data.billing.address.line1", + display_name: "line1", + field_type: "user_address_line1", + value: "1467", + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + email: { + required_field: "email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch.example@gmail.com", + }, + "billing.address.city": { + required_field: "payment_method_data.billing.address.city", + display_name: "city", + field_type: "user_address_city", + value: "San Fransico", + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithNames: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["bankofamerica"], + }, + ], + required_fields: { + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithEmail: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["bankofamerica"], + }, + ], + required_fields: { + email: { + required_field: "email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch_sdk_demo_id1@gmail.com", + }, + }, + }, + ], + }, + ], + }, + }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js b/cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js index 6dfe0131bc3d..708a8660d520 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js @@ -30,6 +30,9 @@ export const connectorDetails = { }, }, "3DSManualCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -41,13 +44,15 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", }, }, }, "3DSAutoCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -59,7 +64,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", }, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js b/cypress-tests/cypress/e2e/PaymentUtils/Commons.js index a0eb936152b2..28b85c854465 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Commons.js @@ -8,9 +8,9 @@ const globalState = new State({ connectorAuthFilePath: Cypress.env("CONNECTOR_AUTH_FILE_PATH"), }); -const connectorName = normalise(globalState.get("connectorId")); +const connectorName = normalize(globalState.get("connectorId")); -function normalise(input) { +function normalize(input) { const exceptions = { bankofamerica: "Bank of America", cybersource: "Cybersource", @@ -18,7 +18,7 @@ function normalise(input) { paypal: "Paypal", wellsfargo: "Wellsfargo", fiuu: "Fiuu", - noon: "Noon" + noon: "Noon", // Add more known exceptions here }; @@ -98,6 +98,49 @@ const multiUseMandateData = { }, }; +export const cardRequiredField = { + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, +}; + +export const fullNameRequiredField = { + "billing.address.last_name": { + required_field: "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "billing.address.first_name": { + required_field: "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, +}; + +export const billingRequiredField = {}; /* `getDefaultExchange` contains the default Request and Response to be considered if none provided. `getCustomExchange` takes in 2 optional fields named as Request and Response. @@ -143,6 +186,7 @@ export const getCustomExchange = (overrides) => { return { ...defaultExchange, + ...(overrides.Configs ? { Configs: overrides.Configs } : {}), Request: { ...defaultExchange.Request, ...(overrides.Request || {}), @@ -1075,7 +1119,7 @@ export const connectorDetails = { error: { error_type: "invalid_request", message: "Json deserialize error: invalid card number length", - code: "IR_06" + code: "IR_06", }, }, }, @@ -1182,8 +1226,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `United`, expected one of `AED`, `AFN`, `ALL`, `AMD`, `ANG`, `AOA`, `ARS`, `AUD`, `AWG`, `AZN`, `BAM`, `BBD`, `BDT`, `BGN`, `BHD`, `BIF`, `BMD`, `BND`, `BOB`, `BRL`, `BSD`, `BTN`, `BWP`, `BYN`, `BZD`, `CAD`, `CDF`, `CHF`, `CLP`, `CNY`, `COP`, `CRC`, `CUP`, `CVE`, `CZK`, `DJF`, `DKK`, `DOP`, `DZD`, `EGP`, `ERN`, `ETB`, `EUR`, `FJD`, `FKP`, `GBP`, `GEL`, `GHS`, `GIP`, `GMD`, `GNF`, `GTQ`, `GYD`, `HKD`, `HNL`, `HRK`, `HTG`, `HUF`, `IDR`, `ILS`, `INR`, `IQD`, `IRR`, `ISK`, `JMD`, `JOD`, `JPY`, `KES`, `KGS`, `KHR`, `KMF`, `KPW`, `KRW`, `KWD`, `KYD`, `KZT`, `LAK`, `LBP`, `LKR`, `LRD`, `LSL`, `LYD`, `MAD`, `MDL`, `MGA`, `MKD`, `MMK`, `MNT`, `MOP`, `MRU`, `MUR`, `MVR`, `MWK`, `MXN`, `MYR`, `MZN`, `NAD`, `NGN`, `NIO`, `NOK`, `NPR`, `NZD`, `OMR`, `PAB`, `PEN`, `PGK`, `PHP`, `PKR`, `PLN`, `PYG`, `QAR`, `RON`, `RSD`, `RUB`, `RWF`, `SAR`, `SBD`, `SCR`, `SDG`, `SEK`, `SGD`, `SHP`, `SLE`, `SLL`, `SOS`, `SRD`, `SSP`, `STN`, `SVC`, `SYP`, `SZL`, `THB`, `TJS`, `TMT`, `TND`, `TOP`, `TRY`, `TTD`, `TWD`, `TZS`, `UAH`, `UGX`, `USD`, `UYU`, `UZS`, `VES`, `VND`, `VUV`, `WST`, `XAF`, `XCD`, `XOF`, `XPF`, `YER`, `ZAR`, `ZMW`, `ZWL`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `United`, expected one of `AED`, `AFN`, `ALL`, `AMD`, `ANG`, `AOA`, `ARS`, `AUD`, `AWG`, `AZN`, `BAM`, `BBD`, `BDT`, `BGN`, `BHD`, `BIF`, `BMD`, `BND`, `BOB`, `BRL`, `BSD`, `BTN`, `BWP`, `BYN`, `BZD`, `CAD`, `CDF`, `CHF`, `CLP`, `CNY`, `COP`, `CRC`, `CUP`, `CVE`, `CZK`, `DJF`, `DKK`, `DOP`, `DZD`, `EGP`, `ERN`, `ETB`, `EUR`, `FJD`, `FKP`, `GBP`, `GEL`, `GHS`, `GIP`, `GMD`, `GNF`, `GTQ`, `GYD`, `HKD`, `HNL`, `HRK`, `HTG`, `HUF`, `IDR`, `ILS`, `INR`, `IQD`, `IRR`, `ISK`, `JMD`, `JOD`, `JPY`, `KES`, `KGS`, `KHR`, `KMF`, `KPW`, `KRW`, `KWD`, `KYD`, `KZT`, `LAK`, `LBP`, `LKR`, `LRD`, `LSL`, `LYD`, `MAD`, `MDL`, `MGA`, `MKD`, `MMK`, `MNT`, `MOP`, `MRU`, `MUR`, `MVR`, `MWK`, `MXN`, `MYR`, `MZN`, `NAD`, `NGN`, `NIO`, `NOK`, `NPR`, `NZD`, `OMR`, `PAB`, `PEN`, `PGK`, `PHP`, `PKR`, `PLN`, `PYG`, `QAR`, `RON`, `RSD`, `RUB`, `RWF`, `SAR`, `SBD`, `SCR`, `SDG`, `SEK`, `SGD`, `SHP`, `SLE`, `SLL`, `SOS`, `SRD`, `SSP`, `STN`, `SVC`, `SYP`, `SZL`, `THB`, `TJS`, `TMT`, `TND`, `TOP`, `TRY`, `TTD`, `TWD`, `TZS`, `UAH`, `UGX`, `USD`, `UYU`, `UZS`, `VES`, `VND`, `VUV`, `WST`, `XAF`, `XCD`, `XOF`, `XPF`, `YER`, `ZAR`, `ZMW`, `ZWL`", + code: "IR_06", }, }, }, @@ -1210,8 +1255,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `auto`, expected one of `automatic`, `manual`, `manual_multiple`, `scheduled`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `auto`, expected one of `automatic`, `manual`, `manual_multiple`, `scheduled`", + code: "IR_06", }, }, }, @@ -1237,8 +1283,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `this_supposed_to_be_a_card`, expected one of `card`, `card_redirect`, `pay_later`, `wallet`, `bank_redirect`, `bank_transfer`, `crypto`, `bank_debit`, `reward`, `real_time_payment`, `upi`, `voucher`, `gift_card`, `open_banking`, `mobile_payment`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `this_supposed_to_be_a_card`, expected one of `card`, `card_redirect`, `pay_later`, `wallet`, `bank_redirect`, `bank_transfer`, `crypto`, `bank_debit`, `reward`, `real_time_payment`, `upi`, `voucher`, `gift_card`, `open_banking`, `mobile_payment`", + code: "IR_06", }, }, }, @@ -1379,6 +1426,96 @@ export const connectorDetails = { }, }, }), + PaymentWithoutBilling: { + Request: { + currency: "USD", + customer_acceptance: null, + setup_future_usage: "off_session", + authentication_type: "no_three_ds", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, + PaymentWithBilling: { + Request: { + currency: "USD", + setup_future_usage: "off_session", + billing: { + address: { + line1: "1467", + line2: "CA", + line3: "Harrison Street", + city: "San Fransico", + state: "CA", + zip: "94122", + country: "PL", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9111222333", + country_code: "+91", + }, + }, + email: "hyperswitch.example@gmail.com", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, + PaymentWithFullName: { + Request: { + currency: "USD", + setup_future_usage: "off_session", + billing: { + address: { + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9111222333", + country_code: "+91", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, + PaymentWithBillingEmail: { + Request: { + currency: "USD", + setup_future_usage: "off_session", + email: "hyperswitch_sdk_demo_id1@gmail.com", + billing: { + address: { + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9111222333", + country_code: "+91", + }, + email: "hyperswitch.example@gmail.com", + }, + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, }, upi_pm: { PaymentIntent: getCustomExchange({ @@ -1417,4 +1554,67 @@ export const connectorDetails = { }, }), }, + pm_list: { + PmListResponse: { + PmListNull: { + payment_methods: [], + }, + pmListDynamicFieldWithoutBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [], + required_fields: {}, + }, + ], + }, + ], + }, + pmListDynamicFieldWithBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [], + required_fields: {}, + }, + ], + }, + ], + }, + pmListDynamicFieldWithNames: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [], + required_fields: {}, + }, + ], + }, + ], + }, + pmListDynamicFieldWithEmail: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [], + required_fields: {}, + }, + ], + }, + ], + }, + }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js b/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js index c0fcfdd1b53a..97a5bd0971c0 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js @@ -107,6 +107,12 @@ export const connectorDetails = { }, }, PaymentIntentOffSession: { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["incrementalAuth"], + value: "connector_2", + }, + }, Request: { currency: "USD", amount: 6500, @@ -123,6 +129,11 @@ export const connectorDetails = { }, }, "3DSManualCapture": { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -142,6 +153,11 @@ export const connectorDetails = { }, }, "3DSAutoCapture": { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -161,6 +177,11 @@ export const connectorDetails = { }, }, No3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -181,6 +202,11 @@ export const connectorDetails = { }, }, No3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -201,6 +227,11 @@ export const connectorDetails = { }, }, Capture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -220,6 +251,11 @@ export const connectorDetails = { }, }, PartialCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: {}, Response: { status: 200, @@ -232,6 +268,11 @@ export const connectorDetails = { }, }, Void: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: {}, Response: { status: 200, @@ -241,6 +282,11 @@ export const connectorDetails = { }, }, Refund: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -257,6 +303,11 @@ export const connectorDetails = { }, }, manualPaymentRefund: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -278,6 +329,11 @@ export const connectorDetails = { }, }, manualPaymentPartialRefund: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -299,6 +355,11 @@ export const connectorDetails = { }, }, PartialRefund: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -315,6 +376,11 @@ export const connectorDetails = { }, }, SyncRefund: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -330,7 +396,26 @@ export const connectorDetails = { }, }, }, + IncrementalAuth: { + Request: { + amount: 7000, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + amount: 7000, + amount_capturable: 7000, + amount_received: null, + }, + }, + }, MandateSingleUse3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -347,6 +432,11 @@ export const connectorDetails = { }, }, MandateSingleUse3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -363,6 +453,11 @@ export const connectorDetails = { }, }, MandateSingleUseNo3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -379,6 +474,11 @@ export const connectorDetails = { }, }, MandateSingleUseNo3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -395,6 +495,11 @@ export const connectorDetails = { }, }, MandateMultiUseNo3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -411,6 +516,11 @@ export const connectorDetails = { }, }, MandateMultiUseNo3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -427,6 +537,11 @@ export const connectorDetails = { }, }, MandateMultiUse3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -443,6 +558,11 @@ export const connectorDetails = { }, }, MandateMultiUse3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -459,6 +579,11 @@ export const connectorDetails = { }, }, MITAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: {}, Response: { status: 200, @@ -468,6 +593,11 @@ export const connectorDetails = { }, }, MITManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: {}, Response: { status: 200, @@ -477,6 +607,11 @@ export const connectorDetails = { }, }, ZeroAuthMandate: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -507,6 +642,11 @@ export const connectorDetails = { }, }, ZeroAuthConfirmPayment: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_type: "setup_mandate", payment_method: "card", @@ -524,6 +664,11 @@ export const connectorDetails = { }, }, SaveCardUseNo3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_type: "debit", @@ -549,6 +694,11 @@ export const connectorDetails = { }, }, SaveCardUseNo3DSAutoCaptureOffSession: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_type: "debit", @@ -573,6 +723,12 @@ export const connectorDetails = { }, }, SaveCardUseNo3DSManualCaptureOffSession: { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["incrementalAuth"], + value: "connector_2", + }, + }, Request: { payment_method: "card", payment_method_type: "debit", @@ -597,6 +753,11 @@ export const connectorDetails = { }, }, SaveCardConfirmAutoCaptureOffSession: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { setup_future_usage: "off_session", }, @@ -608,6 +769,11 @@ export const connectorDetails = { }, }, SaveCardConfirmManualCaptureOffSession: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { setup_future_usage: "off_session", }, @@ -619,6 +785,11 @@ export const connectorDetails = { }, }, SaveCardUseNo3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -643,6 +814,11 @@ export const connectorDetails = { }, }, PaymentMethodIdMandateNo3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -667,6 +843,11 @@ export const connectorDetails = { }, }, PaymentMethodIdMandateNo3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -691,6 +872,11 @@ export const connectorDetails = { }, }, PaymentMethodIdMandate3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -716,6 +902,11 @@ export const connectorDetails = { }, }, PaymentMethodIdMandate3DSManualCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + value: "connector_1", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -740,4 +931,255 @@ export const connectorDetails = { }, }, }, + pm_list: { + PmListResponse: { + PmListNull: { + payment_methods: [], + }, + pmListDynamicFieldWithoutBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["cybersource"], + }, + ], + required_fields: { + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: null, + }, + "billing.address.state": { + required_field: "payment_method_data.billing.address.state", + display_name: "state", + field_type: "user_address_state", + value: null, + }, + "billing.email": { + required_field: "payment_method_data.billing.email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch_sdk_demo_id@gmail.com", + }, + "billing.address.zip": { + required_field: "payment_method_data.billing.address.zip", + display_name: "zip", + field_type: "user_address_pincode", + value: null, + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + "billing.address.line1": { + required_field: "payment_method_data.billing.address.line1", + display_name: "line1", + field_type: "user_address_line1", + value: null, + }, + "billing.address.city": { + required_field: "payment_method_data.billing.address.city", + display_name: "city", + field_type: "user_address_city", + value: null, + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithBilling: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["cybersource"], + }, + ], + required_fields: { + "billing.address.city": { + required_field: "payment_method_data.billing.address.city", + display_name: "city", + field_type: "user_address_city", + value: "San Fransico", + }, + "billing.address.state": { + required_field: "payment_method_data.billing.address.state", + display_name: "state", + field_type: "user_address_state", + value: "CA", + }, + "billing.address.zip": { + required_field: "payment_method_data.billing.address.zip", + display_name: "zip", + field_type: "user_address_pincode", + value: "94122", + }, + "billing.address.country": { + required_field: + "payment_method_data.billing.address.country", + display_name: "country", + field_type: { + user_address_country: { + options: ["ALL"], + }, + }, + value: "PL", + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "billing.email": { + required_field: "payment_method_data.billing.email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch.example@gmail.com", + }, + "payment_method_data.card.card_cvc": { + required_field: "payment_method_data.card.card_cvc", + display_name: "card_cvc", + field_type: "user_card_cvc", + value: null, + }, + "billing.address.line1": { + required_field: "payment_method_data.billing.address.line1", + display_name: "line1", + field_type: "user_address_line1", + value: "1467", + }, + "payment_method_data.card.card_exp_month": { + required_field: "payment_method_data.card.card_exp_month", + display_name: "card_exp_month", + field_type: "user_card_expiry_month", + value: null, + }, + "payment_method_data.card.card_number": { + required_field: "payment_method_data.card.card_number", + display_name: "card_number", + field_type: "user_card_number", + value: null, + }, + "payment_method_data.card.card_exp_year": { + required_field: "payment_method_data.card.card_exp_year", + display_name: "card_exp_year", + field_type: "user_card_expiry_year", + value: null, + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithNames: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["cybersource"], + }, + ], + required_fields: { + "billing.address.last_name": { + required_field: + "payment_method_data.billing.address.last_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "Doe", + }, + "billing.address.first_name": { + required_field: + "payment_method_data.billing.address.first_name", + display_name: "card_holder_name", + field_type: "user_full_name", + value: "joseph", + }, + }, + }, + ], + }, + ], + }, + pmListDynamicFieldWithEmail: { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["cybersource"], + }, + ], + required_fields: { + "billing.email": { + required_field: "payment_method_data.billing.email", + display_name: "email", + field_type: "user_email_address", + value: "hyperswitch.example@gmail.com", + }, + }, + }, + ], + }, + ], + }, + }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Elavon.js b/cypress-tests/cypress/e2e/PaymentUtils/Elavon.js index bb34e805a5a3..6755dd16e700 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Elavon.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Elavon.js @@ -1,571 +1,572 @@ const successfulNo3DSCardDetails = { - card_number: "4111111111111111", - card_exp_month: "06", - card_exp_year: "50", - card_holder_name: "joseph Doe", - card_cvc: "123", + card_number: "4111111111111111", + card_exp_month: "06", + card_exp_year: "50", + card_holder_name: "joseph Doe", + card_cvc: "123", }; + const singleUseMandateData = { - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", }, - mandate_type: { - single_use: { - amount: 8000, - currency: "USD", - }, + }, + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", }, + }, }; const multiUseMandateData = { - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, +}; +export const connectorDetails = { + card_pm: { + PaymentIntent: { + Request: { + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + billing: { + address: { + line1: "1467", + line2: "CA", + line3: "CA", + city: "Florence", + state: "Tuscany", + zip: "12345", + country: "IT", + first_name: "Max", + last_name: "Mustermann", + }, + email: "mauro.morandi@nexi.it", + phone: { + number: "9123456789", + country_code: "+91", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, + No3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + email: "mauro.morandi@nexi.it", + }, + }, + billing: { + email: "mauro.morandi@nexi.it", + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + No3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + email: "mauro.morandi@nexi.it", + }, + }, + billing: { + email: "mauro.morandi@nexi.it", + }, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + manualPaymentPartialRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + manualPaymentRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateMultiUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "NL", + first_name: "joseph", + last_name: "Doe", + }, + email: "johndoe@gmail.com", + }, + }, + currency: "USD", + mandate_data: multiUseMandateData, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateMultiUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "NL", + first_name: "joseph", + last_name: "Doe", + }, + email: "johndoe@gmail.com", + }, + }, + currency: "USD", + mandate_data: multiUseMandateData, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + SaveCardUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + email: "mauro.morandi@nexi.it", + }, + }, + currency: "USD", + setup_future_usage: "on_session", + 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", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, + }, }, - mandate_type: { - multi_use: { - amount: 8000, - currency: "USD", + SaveCardUseNo3DSAutoCaptureOffSession: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "NL", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9123456789", + country_code: "+91", + }, + email: "mauro.morandi@nexi.it", + }, }, + setup_future_usage: "off_session", + 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", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, }, -}; -export const connectorDetails = { - card_pm: { - PaymentIntent: { - Request: { - currency: "USD", - customer_acceptance: null, - setup_future_usage: "on_session", - billing: { - address: { - line1: "1467", - line2: "CA", - line3: "CA", - city: "Florence", - state: "Tuscany", - zip: "12345", - country: "IT", - first_name: "Max", - last_name: "Mustermann", - }, - email: "mauro.morandi@nexi.it", - phone: { - number: "9123456789", - country_code: "+91", - }, - }, - }, - Response: { - status: 200, - body: { - status: "requires_payment_method", - }, - }, + SaveCardUseNo3DSManualCaptureOffSession: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "NL", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9123456789", + country_code: "+91", + }, + email: "mauro.morandi@nexi.it", + }, }, - No3DSManualCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - email: "mauro.morandi@nexi.it", - }, - }, - billing: { - email: "mauro.morandi@nexi.it", - }, - currency: "USD", - customer_acceptance: null, - setup_future_usage: "on_session", - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + setup_future_usage: "off_session", + 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", + }, }, - No3DSAutoCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - email: "mauro.morandi@nexi.it", - }, - }, - billing: { - email: "mauro.morandi@nexi.it", - }, - currency: "USD", - customer_acceptance: null, - setup_future_usage: "on_session", - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, - }, manualPaymentPartialRefund: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, - manualPaymentRefund: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + }, + SaveCardConfirmAutoCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - MandateMultiUseNo3DSAutoCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - address: { - line1: "1467", - line2: "Harrison Street", - line3: "Harrison Street", - city: "San Fransico", - state: "California", - zip: "94122", - country: "NL", - first_name: "joseph", - last_name: "Doe", - }, - email: "johndoe@gmail.com" - }, - }, - currency: "USD", - mandate_data: multiUseMandateData, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + }, + SaveCardConfirmManualCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, - MandateMultiUseNo3DSManualCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - address: { - line1: "1467", - line2: "Harrison Street", - line3: "Harrison Street", - city: "San Fransico", - state: "California", - zip: "94122", - country: "NL", - first_name: "joseph", - last_name: "Doe", - }, - email: "johndoe@gmail.com" - }, - }, - currency: "USD", - mandate_data: multiUseMandateData, - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + }, + }, + SaveCardUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "NL", + first_name: "joseph", + last_name: "Doe", + }, + phone: { + number: "9123456789", + country_code: "+91", + }, + email: "mauro.morandi@nexi.it", + }, }, - SaveCardUseNo3DSAutoCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - email: "mauro.morandi@nexi.it", - - }, - }, - currency: "USD", - setup_future_usage: "on_session", - 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", - }, - }, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + currency: "USD", + setup_future_usage: "on_session", + 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", + }, }, - SaveCardUseNo3DSAutoCaptureOffSession: { - Request: { - payment_method: "card", - payment_method_type: "debit", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - address: { - line1: "1467", - line2: "Harrison Street", - line3: "Harrison Street", - city: "San Fransico", - state: "California", - zip: "94122", - country: "NL", - first_name: "joseph", - last_name: "Doe", - }, - phone: { - number: "9123456789", - country_code: "+91", - }, - email: "mauro.morandi@nexi.it", - }, - }, - setup_future_usage: "off_session", - 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", - }, - }, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, - SaveCardUseNo3DSManualCaptureOffSession: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - address: { - line1: "1467", - line2: "Harrison Street", - line3: "Harrison Street", - city: "San Fransico", - state: "California", - zip: "94122", - country: "NL", - first_name: "joseph", - last_name: "Doe", - }, - phone: { - number: "9123456789", - country_code: "+91", - }, - email: "mauro.morandi@nexi.it", - }, - }, - setup_future_usage: "off_session", - 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", - }, - }, - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + }, + }, + MandateSingleUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + email: "mauro.morandi@nexi.it", + }, }, - SaveCardConfirmAutoCaptureOffSession: { - Request: { - setup_future_usage: "off_session", - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - SaveCardConfirmManualCaptureOffSession: { - Request: { - setup_future_usage: "off_session", - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + }, + }, + MandateSingleUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + billing: { + email: "mauro.morandi@nexi.it", + }, }, - SaveCardUseNo3DSManualCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - address: { - line1: "1467", - line2: "Harrison Street", - line3: "Harrison Street", - city: "San Fransico", - state: "California", - zip: "94122", - country: "NL", - first_name: "joseph", - last_name: "Doe", - }, - phone: { - number: "9123456789", - country_code: "+91", - }, - email: "mauro.morandi@nexi.it", - }, - }, - currency: "USD", - setup_future_usage: "on_session", - 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", - }, - }, - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, - MandateSingleUseNo3DSAutoCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - email: "mauro.morandi@nexi.it", - }, - }, - currency: "USD", - mandate_data: singleUseMandateData, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + }, + Capture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, }, - MandateSingleUseNo3DSManualCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - billing: { - email: "mauro.morandi@nexi.it", - }, - }, - currency: "USD", - mandate_data: singleUseMandateData, - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", + amount: 6500, + amount_capturable: 0, + amount_received: 6500, }, - Capture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - amount: 6500, - amount_capturable: 0, - amount_received: 6500, - }, - }, + }, + }, + PartialCapture: { + Request: {}, + Response: { + status: 200, + body: { + status: "partially_captured", + amount: 6500, + amount_capturable: 0, + amount_received: 100, }, - PartialCapture: { - Request: {}, - Response: { - status: 200, - body: { - status: "partially_captured", - amount: 6500, - amount_capturable: 0, - amount_received: 100, - }, - }, + }, + }, + Refund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, }, - Refund: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - VoidAfterConfirm: { - Request: {}, - Response: { - status: 501, - body: { - error: { - type: "invalid_request", - message: "Cancel/Void flow is not implemented", - code: "IR_00" - } - } - }, + }, + }, + VoidAfterConfirm: { + Request: {}, + Response: { + status: 501, + body: { + error: { + type: "invalid_request", + message: "Cancel/Void flow is not implemented", + code: "IR_00", + }, }, - PartialRefund: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + }, + PartialRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, }, - SyncRefund: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - customer_acceptance: null, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - PaymentMethodIdMandateNo3DSAutoCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - currency: "USD", - billing: { - email: "mauro.morandi@nexi.it", - }, - mandate_data: null, - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, - }, - Response: { - status: 200, - body: { - status: "succeeded", - }, - }, + }, + }, + SyncRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, }, - PaymentMethodIdMandateNo3DSManualCapture: { - Request: { - payment_method: "card", - payment_method_data: { - card: successfulNo3DSCardDetails, - }, - billing: { - email: "mauro.morandi@nexi.it", - }, - currency: "USD", - mandate_data: null, - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, - }, - Response: { - status: 200, - body: { - status: "requires_capture", - }, - }, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + PaymentMethodIdMandateNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "USD", + billing: { + email: "mauro.morandi@nexi.it", + }, + mandate_data: null, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + PaymentMethodIdMandateNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + billing: { + email: "mauro.morandi@nexi.it", + }, + currency: "USD", + mandate_data: null, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, + }, }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js b/cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js index d82a5f128d68..996356117ab0 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js @@ -299,7 +299,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, currency: "USD", @@ -399,9 +399,9 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, - }, + }, currency: "USD", mandate_data: null, customer_acceptance: { @@ -437,7 +437,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, currency: "USD", @@ -475,7 +475,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, currency: "USD", @@ -513,7 +513,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, setup_future_usage: "off_session", @@ -550,7 +550,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, setup_future_usage: "off_session", @@ -609,7 +609,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, currency: "USD", @@ -647,7 +647,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, currency: "USD", @@ -686,7 +686,7 @@ export const connectorDetails = { first_name: "joseph", last_name: "Doe", }, - email: "johndoe@gmail.com" + email: "johndoe@gmail.com", }, }, mandate_data: null, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js b/cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js index 7f4927d347f6..3b77a0ad6e7f 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js @@ -1,29 +1,84 @@ -import { getCustomExchange } from "./Commons"; - const successfulNo3DSCardDetails = { - card_number: "4012000033330026", - card_exp_month: "01", - card_exp_year: "50", + card_number: "4111111111111111", + card_exp_month: "08", + card_exp_year: "35", card_holder_name: "joseph Doe", - card_cvc: "123", + card_cvc: "999", }; const successfulThreeDSTestCardDetails = { card_number: "4349940199004549", card_exp_month: "12", - card_exp_year: "30", + card_exp_year: "35", card_holder_name: "joseph Doe", card_cvc: "396", }; +const customerAcceptance = { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, +}; + +const multiUseMandateData = { + customer_acceptance: customerAcceptance, + mandate_type: { + multi_use: { + amount: 8000, + currency: "EUR", + }, + }, +}; + +const singleUseMandateData = { + customer_acceptance: customerAcceptance, + mandate_type: { + multi_use: { + amount: 8000, + currency: "EUR", + }, + }, +}; + +const billingAddress = { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "IT", + first_name: "joseph", + last_name: "Doe", + }, + email: "mauro.morandi@nexi.it", + phone: { + number: "9123456789", + country_code: "+91", + }, +}; + +const no3DSNotSupportedResponseBody = { + error: { + type: "invalid_request", + message: "No threeds is not supported", + code: "IR_00", + }, +}; + export const connectorDetails = { card_pm: { PaymentIntent: { Request: { currency: "EUR", - amount: 3545, + amount: 6500, customer_acceptance: null, setup_future_usage: "on_session", + billing: billingAddress, }, Response: { status: 200, @@ -32,27 +87,29 @@ export const connectorDetails = { }, }, }, + PaymentIntentOffSession: { + Request: { + currency: "EUR", + amount: 6500, + authentication_type: "no_three_ds", + customer_acceptance: null, + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + setup_future_usage: "off_session", + }, + }, + }, "3DSManualCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", - billing: { - address: { - line1: "1467", - line2: "CA", - line3: "CA", - city: "Florence", - state: "Tuscany", - zip: "12345", - country: "IT", - first_name: "Max", - last_name: "Mustermann", - }, - email: "mauro.morandi@nexi.it", - phone: { - number: "9123456789", - country_code: "+91", - }, - }, + billing: billingAddress, payment_method_data: { card: successfulThreeDSTestCardDetails, }, @@ -62,31 +119,17 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "requires_capture", + status: "requires_customer_action", }, }, }, "3DSAutoCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", - billing: { - address: { - line1: "1467", - line2: "CA", - line3: "CA", - city: "Florence", - state: "Tuscany", - zip: "12345", - country: "IT", - first_name: "Max", - last_name: "Mustermann", - }, - email: "mauro.morandi@nexi.it", - phone: { - number: "9123456789", - country_code: "+91", - }, - }, + billing: billingAddress, payment_method_data: { card: successfulThreeDSTestCardDetails, }, @@ -100,7 +143,42 @@ export const connectorDetails = { }, }, }, + No3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + customer_acceptance: null, + setup_future_usage: "on_session", + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, + No3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + customer_acceptance: null, + setup_future_usage: "on_session", + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, Capture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -112,20 +190,23 @@ export const connectorDetails = { status: 200, body: { status: "processing", - amount: 3545, - amount_capturable: 0, - amount_received: 3545, + amount: 6500, + amount_capturable: 6500, + amount_received: null, }, }, }, PartialCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: {}, Response: { status: 200, body: { status: "processing", - amount: 3545, - amount_capturable: 0, + amount: 6500, + amount_capturable: 6500, amount_received: 100, }, }, @@ -140,6 +221,9 @@ export const connectorDetails = { }, }, Refund: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -150,11 +234,14 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing", + status: "pending", }, }, }, PartialRefund: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -165,7 +252,7 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing", + status: "pending", }, }, }, @@ -184,5 +271,329 @@ export const connectorDetails = { }, }, }, + MandateMultiUse3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + mandate_data: multiUseMandateData, + billing: billingAddress, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + MandateMultiUse3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + mandate_data: multiUseMandateData, + billing: billingAddress, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + MandateMultiUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + mandate_data: multiUseMandateData, + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, + MandateMultiUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + mandate_data: multiUseMandateData, + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, + MandateSingleUse3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + mandate_data: singleUseMandateData, + billing: billingAddress, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + MandateSingleUse3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + mandate_data: singleUseMandateData, + billing: billingAddress, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + MandateSingleUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + mandate_data: singleUseMandateData, + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, + MandateSingleUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + mandate_data: singleUseMandateData, + billing: billingAddress, + }, + Response: { + status: 400, + body: no3DSNotSupportedResponseBody, + }, + }, + manualPaymentRefund: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "pending", + }, + }, + }, + ZeroAuthMandate: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + PaymentMethodIdMandateNo3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + amount: 6500, + mandate_data: null, + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + PaymentMethodIdMandateNo3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + amount: 6500, + mandate_data: null, + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + PaymentMethodIdMandate3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + amount: 6500, + mandate_data: null, + authentication_type: "three_ds", + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + PaymentMethodIdMandate3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDSTestCardDetails, + }, + currency: "EUR", + amount: 6500, + mandate_data: null, + authentication_type: "three_ds", + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + SaveCardUseNo3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + currency: "EUR", + billing: billingAddress, + setup_future_usage: "on_session", + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + SaveCardUseNo3DSAutoCaptureOffSession: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + currency: "EUR", + billing: billingAddress, + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + setup_future_usage: "off_session", + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + SaveCardUseNo3DSManualCaptureOffSession: { + Configs: { + TRIGGER_SKIP: true, + }, + Request: { + payment_method: "card", + currency: "EUR", + billing: billingAddress, + payment_method_type: "debit", + payment_method_data: { + card: successfulNo3DSCardDetails, + }, + setup_future_usage: "off_session", + customer_acceptance: customerAcceptance, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Nmi.js b/cypress-tests/cypress/e2e/PaymentUtils/Nmi.js index 2206c516de54..2ece2615b4c1 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Nmi.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Nmi.js @@ -307,6 +307,10 @@ export const connectorDetails = { }, }, PaymentMethodIdMandate3DSAutoCapture: { + Configs: { + // Skipping redirection here for mandate 3ds auto capture as it requires changes from the core + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -317,8 +321,6 @@ export const connectorDetails = { customer_acceptance: customerAcceptance, }, Response: { - // Skipping redirection here for mandate 3ds auto capture as it requires changes from the core - trigger_skip: true, status: 200, body: { status: "requires_customer_action", @@ -326,6 +328,9 @@ export const connectorDetails = { }, }, PaymentMethodIdMandate3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method_data: { card: successfulThreeDSTestCardDetails, @@ -335,8 +340,6 @@ export const connectorDetails = { customer_acceptance: customerAcceptance, }, Response: { - trigger_skip: true, - status: 200, body: { status: "requires_customer_action", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Noon.js b/cypress-tests/cypress/e2e/PaymentUtils/Noon.js index 38b0c0c1117a..6d2a3926972e 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Noon.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Noon.js @@ -63,30 +63,6 @@ const multiUseMandateData = { }, }; -const payment_method_data_no3ds = { - card: { - last4: "4242", - card_type: "CREDIT", - card_network: "Visa", - card_issuer: "STRIPE PAYMENTS UK LIMITED", - card_issuing_country: "UNITEDKINGDOM", - card_isin: "424242", - card_extended_bin: null, - card_exp_month: "01", - card_exp_year: "30", - card_holder_name: null, - payment_checks: { - avs_response: { - code: "Y", - codeRaw: "Y", - }, - card_verification: null, - }, - authentication_data: null, - }, - billing: null, -}; - const payment_method_data_3ds = { card: { last4: "1091", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js b/cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js index 0b3b2820aa51..0a8235141dcc 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js @@ -1,11 +1,3 @@ -const successfulNo3DSCardDetails = { - card_number: "4200000000000000", - card_exp_month: "12", - card_exp_year: "50", - card_holder_name: "Max Mustermann", - card_cvc: "123", -}; - const successfulThreeDSTestCardDetails = { card_number: "4000000000001091", card_exp_month: "12", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js b/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js index a7a4afc07beb..7a4a47f9c312 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js @@ -14,15 +14,17 @@ const successfulThreeDSTestCardDetails = { card_cvc: "123", }; -const singleUseMandateData = { - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, +const customerAcceptance = { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", }, +}; + +const singleUseMandateData = { + customer_acceptance: customerAcceptance, mandate_type: { single_use: { amount: 7000, @@ -32,14 +34,7 @@ const singleUseMandateData = { }; const multiUseMandateData = { - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: customerAcceptance, mandate_type: { multi_use: { amount: 6500, @@ -48,13 +43,12 @@ const multiUseMandateData = { }, }; -const customerAcceptance = { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, +const captureNotSupported = { + type: "invalid_request", + message: "Payment method type not supported", + code: "IR_19", + reason: + "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", }; export const connectorDetails = { @@ -260,13 +254,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -298,13 +286,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -336,13 +318,7 @@ export const connectorDetails = { Response: { status: 200, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -374,13 +350,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -436,13 +406,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -477,13 +441,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -581,13 +539,7 @@ export const connectorDetails = { Response: { status: 400, body: { - error: { - type: "invalid_request", - message: "Payment method type not supported", - code: "IR_19", - reason: - "Capture Not allowed in case of Creating the Subscriber is not supported by Paybox", - }, + error: captureNotSupported, }, }, }, @@ -669,7 +621,7 @@ export const connectorDetails = { error: { error_type: "invalid_request", message: "Json deserialize error: invalid card number length", - code: "IR_06" + code: "IR_06", }, }, }, @@ -776,8 +728,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `United`, expected one of `AED`, `AFN`, `ALL`, `AMD`, `ANG`, `AOA`, `ARS`, `AUD`, `AWG`, `AZN`, `BAM`, `BBD`, `BDT`, `BGN`, `BHD`, `BIF`, `BMD`, `BND`, `BOB`, `BRL`, `BSD`, `BTN`, `BWP`, `BYN`, `BZD`, `CAD`, `CDF`, `CHF`, `CLP`, `CNY`, `COP`, `CRC`, `CUP`, `CVE`, `CZK`, `DJF`, `DKK`, `DOP`, `DZD`, `EGP`, `ERN`, `ETB`, `EUR`, `FJD`, `FKP`, `GBP`, `GEL`, `GHS`, `GIP`, `GMD`, `GNF`, `GTQ`, `GYD`, `HKD`, `HNL`, `HRK`, `HTG`, `HUF`, `IDR`, `ILS`, `INR`, `IQD`, `IRR`, `ISK`, `JMD`, `JOD`, `JPY`, `KES`, `KGS`, `KHR`, `KMF`, `KPW`, `KRW`, `KWD`, `KYD`, `KZT`, `LAK`, `LBP`, `LKR`, `LRD`, `LSL`, `LYD`, `MAD`, `MDL`, `MGA`, `MKD`, `MMK`, `MNT`, `MOP`, `MRU`, `MUR`, `MVR`, `MWK`, `MXN`, `MYR`, `MZN`, `NAD`, `NGN`, `NIO`, `NOK`, `NPR`, `NZD`, `OMR`, `PAB`, `PEN`, `PGK`, `PHP`, `PKR`, `PLN`, `PYG`, `QAR`, `RON`, `RSD`, `RUB`, `RWF`, `SAR`, `SBD`, `SCR`, `SDG`, `SEK`, `SGD`, `SHP`, `SLE`, `SLL`, `SOS`, `SRD`, `SSP`, `STN`, `SVC`, `SYP`, `SZL`, `THB`, `TJS`, `TMT`, `TND`, `TOP`, `TRY`, `TTD`, `TWD`, `TZS`, `UAH`, `UGX`, `USD`, `UYU`, `UZS`, `VES`, `VND`, `VUV`, `WST`, `XAF`, `XCD`, `XOF`, `XPF`, `YER`, `ZAR`, `ZMW`, `ZWL`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `United`, expected one of `AED`, `AFN`, `ALL`, `AMD`, `ANG`, `AOA`, `ARS`, `AUD`, `AWG`, `AZN`, `BAM`, `BBD`, `BDT`, `BGN`, `BHD`, `BIF`, `BMD`, `BND`, `BOB`, `BRL`, `BSD`, `BTN`, `BWP`, `BYN`, `BZD`, `CAD`, `CDF`, `CHF`, `CLP`, `CNY`, `COP`, `CRC`, `CUP`, `CVE`, `CZK`, `DJF`, `DKK`, `DOP`, `DZD`, `EGP`, `ERN`, `ETB`, `EUR`, `FJD`, `FKP`, `GBP`, `GEL`, `GHS`, `GIP`, `GMD`, `GNF`, `GTQ`, `GYD`, `HKD`, `HNL`, `HRK`, `HTG`, `HUF`, `IDR`, `ILS`, `INR`, `IQD`, `IRR`, `ISK`, `JMD`, `JOD`, `JPY`, `KES`, `KGS`, `KHR`, `KMF`, `KPW`, `KRW`, `KWD`, `KYD`, `KZT`, `LAK`, `LBP`, `LKR`, `LRD`, `LSL`, `LYD`, `MAD`, `MDL`, `MGA`, `MKD`, `MMK`, `MNT`, `MOP`, `MRU`, `MUR`, `MVR`, `MWK`, `MXN`, `MYR`, `MZN`, `NAD`, `NGN`, `NIO`, `NOK`, `NPR`, `NZD`, `OMR`, `PAB`, `PEN`, `PGK`, `PHP`, `PKR`, `PLN`, `PYG`, `QAR`, `RON`, `RSD`, `RUB`, `RWF`, `SAR`, `SBD`, `SCR`, `SDG`, `SEK`, `SGD`, `SHP`, `SLE`, `SLL`, `SOS`, `SRD`, `SSP`, `STN`, `SVC`, `SYP`, `SZL`, `THB`, `TJS`, `TMT`, `TND`, `TOP`, `TRY`, `TTD`, `TWD`, `TZS`, `UAH`, `UGX`, `USD`, `UYU`, `UZS`, `VES`, `VND`, `VUV`, `WST`, `XAF`, `XCD`, `XOF`, `XPF`, `YER`, `ZAR`, `ZMW`, `ZWL`", + code: "IR_06", }, }, }, @@ -804,8 +757,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `auto`, expected one of `automatic`, `manual`, `manual_multiple`, `scheduled`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `auto`, expected one of `automatic`, `manual`, `manual_multiple`, `scheduled`", + code: "IR_06", }, }, }, @@ -831,8 +785,9 @@ export const connectorDetails = { body: { error: { error_type: "invalid_request", - message: "Json deserialize error: unknown variant `this_supposed_to_be_a_card`, expected one of `card`, `card_redirect`, `pay_later`, `wallet`, `bank_redirect`, `bank_transfer`, `crypto`, `bank_debit`, `reward`, `real_time_payment`, `upi`, `voucher`, `gift_card`, `open_banking`, `mobile_payment`", - code: "IR_06" + message: + "Json deserialize error: unknown variant `this_supposed_to_be_a_card`, expected one of `card`, `card_redirect`, `pay_later`, `wallet`, `bank_redirect`, `bank_transfer`, `crypto`, `bank_debit`, `reward`, `real_time_payment`, `upi`, `voucher`, `gift_card`, `open_banking`, `mobile_payment`", + code: "IR_06", }, }, }, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js b/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js index 715bfae395cf..a551ed859593 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js @@ -49,6 +49,9 @@ export const connectorDetails = { }, }, "3DSManualCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -60,13 +63,15 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", }, }, }, "3DSAutoCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -78,7 +83,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", }, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js b/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js index 5c899e87d9c2..d68978c43023 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js @@ -1,4 +1,4 @@ -import { getCustomExchange } from "./Commons"; +import { cardRequiredField, getCustomExchange } from "./Commons"; const successfulNo3DSCardDetails = { card_number: "4242424242424242", @@ -90,6 +90,25 @@ const payment_method_data_no3ds = { billing: null, }; +const requiredFields = { + payment_methods: [ + { + payment_method: "card", + payment_method_types: [ + { + payment_method_type: "credit", + card_networks: [ + { + eligible_connectors: ["stripe"], + }, + ], + required_fields: cardRequiredField, + }, + ], + }, + ], +}; + export const connectorDetails = { card_pm: { PaymentIntent: { @@ -944,4 +963,15 @@ export const connectorDetails = { }, }, }, + pm_list: { + PmListResponse: { + PmListNull: { + payment_methods: [], + }, + pmListDynamicFieldWithoutBilling: requiredFields, + pmListDynamicFieldWithBilling: requiredFields, + pmListDynamicFieldWithNames: requiredFields, + pmListDynamicFieldWithEmail: requiredFields, + }, + }, }; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js b/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js index 21975b4dea39..76351c6c4548 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js @@ -36,6 +36,12 @@ const multiUseMandateData = { export const connectorDetails = { card_pm: { PaymentIntent: getCustomExchange({ + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["refundPayment", "syncRefund"], + value: "connector_2", + }, + }, Request: { currency: "USD", customer_acceptance: null, @@ -49,6 +55,12 @@ export const connectorDetails = { }, }), "3DSAutoCapture": { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["refundPayment", "syncRefund"], + value: "connector_2", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -66,6 +78,12 @@ export const connectorDetails = { }, }, No3DSAutoCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["refundPayment", "syncRefund"], + value: "connector_2", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -83,6 +101,12 @@ export const connectorDetails = { }, }, Capture: { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["refundPayment", "syncRefund"], + value: "connector_2", + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -104,6 +128,16 @@ export const connectorDetails = { }, }, PartialCapture: { + Configs: { + CONNECTOR_CREDENTIAL: { + specName: ["refundPayment", "syncRefund"], + value: "connector_2", + }, + DELAY: { + STATUS: true, + TIMEOUT: 15000, + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -138,6 +172,12 @@ export const connectorDetails = { }, }, Refund: { + Configs: { + DELAY: { + STATUS: true, + TIMEOUT: 15000, + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -154,6 +194,12 @@ export const connectorDetails = { }, }, PartialRefund: { + Configs: { + DELAY: { + STATUS: true, + TIMEOUT: 15000, + }, + }, Request: { payment_method: "card", payment_method_data: { @@ -165,12 +211,18 @@ export const connectorDetails = { Response: { status: 200, body: { - error_code: "1", - error_message: "transaction declined (invalid amount)", + reason: "FRAUD", + status: "succeeded", }, }, }, SyncRefund: { + Configs: { + DELAY: { + STATUS: true, + TIMEOUT: 15000, + }, + }, Request: { payment_method: "card", payment_method_data: { diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js b/cypress-tests/cypress/e2e/PaymentUtils/Utils.js index 39d8ab6c8af7..e432c37717bf 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Utils.js @@ -1,13 +1,18 @@ +import { validateConfig } from "../../utils/featureFlags.js"; + import { connectorDetails as adyenConnectorDetails } from "./Adyen.js"; import { connectorDetails as bankOfAmericaConnectorDetails } from "./BankOfAmerica.js"; import { connectorDetails as bluesnapConnectorDetails } from "./Bluesnap.js"; +import { connectorDetails as checkoutConnectorDetails } from "./Checkout.js"; import { connectorDetails as CommonConnectorDetails, updateDefaultStatusCode, } from "./Commons.js"; import { connectorDetails as cybersourceConnectorDetails } from "./Cybersource.js"; import { connectorDetails as datatransConnectorDetails } from "./Datatrans.js"; +import { connectorDetails as elavonConnectorDetails } from "./Elavon.js"; import { connectorDetails as fiservemeaConnectorDetails } from "./Fiservemea.js"; +import { connectorDetails as fiuuConnectorDetails } from "./Fiuu.js"; import { connectorDetails as iatapayConnectorDetails } from "./Iatapay.js"; import { connectorDetails as itaubankConnectorDetails } from "./ItauBank.js"; import { connectorDetails as nexixpayConnectorDetails } from "./Nexixpay.js"; @@ -19,10 +24,7 @@ import { connectorDetails as paypalConnectorDetails } from "./Paypal.js"; import { connectorDetails as stripeConnectorDetails } from "./Stripe.js"; import { connectorDetails as trustpayConnectorDetails } from "./Trustpay.js"; import { connectorDetails as wellsfargoConnectorDetails } from "./WellsFargo.js"; -import { connectorDetails as fiuuConnectorDetails } from "./Fiuu.js"; import { connectorDetails as worldpayConnectorDetails } from "./WorldPay.js"; -import { connectorDetails as checkoutConnectorDetails } from "./Checkout.js"; -import { connectorDetails as elavonConnectorDetails } from "./Elavon.js"; const connectorDetails = { adyen: adyenConnectorDetails, @@ -50,12 +52,13 @@ const connectorDetails = { }; export default function getConnectorDetails(connectorId) { - let x = mergeDetails(connectorId); + const x = mergeDetails(connectorId); return x; } export function getConnectorFlowDetails(connectorData, commonData, key) { - let data = connectorData[key] === undefined ? commonData[key] : connectorData[key]; + const data = + connectorData[key] === undefined ? commonData[key] : connectorData[key]; return data; } @@ -99,21 +102,47 @@ export function getValueByKey(jsonObject, key) { typeof jsonObject === "string" ? JSON.parse(jsonObject) : jsonObject; if (data && typeof data === "object" && key in data) { + // Connector object has multiple keys + if (typeof data[key].connector_account_details === "undefined") { + const keys = Object.keys(data[key]); + + for (let i = 0; i < keys.length; i++) { + const currentItem = data[key][keys[i]]; + + if ( + Object.prototype.hasOwnProperty.call( + currentItem, + "connector_account_details" + ) + ) { + Cypress.env("MULTIPLE_CONNECTORS", { + status: true, + count: keys.length, + }); + + return currentItem; + } + } + } + return data[key]; } else { return null; } } -export const should_continue_further = (res_data) => { - if (res_data.trigger_skip !== undefined) { - return !res_data.trigger_skip; +export const should_continue_further = (data) => { + const resData = data.Response || {}; + const configData = validateConfig(data.Configs) || {}; + + if (typeof configData?.TRIGGER_SKIP !== "undefined") { + return !configData.TRIGGER_SKIP; } if ( - res_data.body.error !== undefined || - res_data.body.error_code !== undefined || - res_data.body.error_message !== undefined + typeof resData.body.error !== "undefined" || + typeof resData.body.error_code !== "undefined" || + typeof resData.body.error_message !== "undefined" ) { return false; } else { @@ -139,9 +168,12 @@ export function defaultErrorHandler(response, response_data) { if (typeof response.body.error === "object") { for (const key in response_data.body.error) { // Check if the error message is a Json deserialize error - let apiResponseContent = response.body.error[key]; - let expectedContent = response_data.body.error[key]; - if (typeof apiResponseContent === "string" && apiResponseContent.includes("Json deserialize error")) { + const apiResponseContent = response.body.error[key]; + const expectedContent = response_data.body.error[key]; + if ( + typeof apiResponseContent === "string" && + apiResponseContent.includes("Json deserialize error") + ) { expect(apiResponseContent).to.include(expectedContent); } else { expect(apiResponseContent).to.equal(expectedContent); diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js b/cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js index 56f3caba8fac..38a5b637040a 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js @@ -68,6 +68,9 @@ export const connectorDetails = { }, }, "3DSManualCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -79,13 +82,15 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_capture", }, }, }, "3DSAutoCapture": { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -97,7 +102,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", @@ -227,6 +231,9 @@ export const connectorDetails = { }, }, MandateSingleUse3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -237,7 +244,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "succeeded", @@ -245,6 +251,9 @@ export const connectorDetails = { }, }, MandateSingleUse3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -255,7 +264,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", @@ -327,6 +335,9 @@ export const connectorDetails = { }, }, MandateMultiUse3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -337,7 +348,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_capture", @@ -345,6 +355,9 @@ export const connectorDetails = { }, }, MandateMultiUse3DSManualCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -355,7 +368,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_capture", @@ -493,6 +505,9 @@ export const connectorDetails = { }, }, PaymentMethodIdMandate3DSAutoCapture: { + Configs: { + TRIGGER_SKIP: true, + }, Request: { payment_method: "card", payment_method_data: { @@ -512,7 +527,6 @@ export const connectorDetails = { }, Response: { status: 200, - trigger_skip: true, body: { status: "requires_customer_action", }, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index d45458369c59..557e4b23ee43 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -1,4 +1,3 @@ - const billing = { address: { line1: "1467", @@ -9,21 +8,23 @@ const billing = { zip: "94122", country: "US", first_name: "John", - last_name: "Doe" - } + last_name: "Doe", + }, }; const browser_info = { - "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", - "color_depth": 24, - "screen_height": 723, - "screen_width": 1536, - "time_zone": 0, - "java_enabled": true, - "java_script_enabled": true, - "ip_address": "127.0.0.1" + user_agent: + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", + accept_header: + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + language: "nl-NL", + color_depth: 24, + screen_height: 723, + screen_width: 1536, + time_zone: 0, + java_enabled: true, + java_script_enabled: true, + ip_address: "127.0.0.1", }; const successfulNoThreeDsCardDetailsRequest = { @@ -55,9 +56,9 @@ const paymentMethodDataNoThreeDsResponse = { card_exp_year: "30", card_holder_name: null, payment_checks: null, - authentication_data: null + authentication_data: null, }, - billing: null + billing: null, }; const payment_method_data_3ds = { @@ -73,12 +74,12 @@ const payment_method_data_3ds = { card_exp_year: "30", card_holder_name: null, payment_checks: null, - authentication_data: null + authentication_data: null, }, - billing: null + billing: null, }; -const offileCustomerAcceptance = { +const customerAcceptance = { acceptance_type: "offline", accepted_at: "1963-05-03T04:07:52.723Z", online: { @@ -88,7 +89,7 @@ const offileCustomerAcceptance = { }; const singleUseMandateData = { - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, mandate_type: { single_use: { amount: 8000, @@ -205,10 +206,11 @@ export const connectorDetails = { ResponseCustom: { body: { type: "invalid_request", - message: "You cannot cancel this payment because it has status processing", + message: + "You cannot cancel this payment because it has status processing", code: "IR_16", - } - } + }, + }, }, VoidAfterConfirm: { Request: {}, @@ -227,7 +229,7 @@ export const connectorDetails = { }, currency: "USD", setup_future_usage: "on_session", - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { body: { @@ -242,7 +244,7 @@ export const connectorDetails = { card: successfulNoThreeDsCardDetailsRequest, }, setup_future_usage: "off_session", - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -271,14 +273,14 @@ export const connectorDetails = { currency: "USD", setup_future_usage: "on_session", browser_info, - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, body: { - status: "succeeded" + status: "succeeded", }, - } + }, }, SaveCardUseNo3DSAutoCaptureOffSession: { Request: { @@ -288,7 +290,7 @@ export const connectorDetails = { card: successfulNoThreeDsCardDetailsRequest, }, setup_future_usage: "off_session", - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -396,7 +398,7 @@ export const connectorDetails = { Request: {}, Response: { body: { - status: "succeeded" + status: "succeeded", }, }, }, @@ -404,9 +406,9 @@ export const connectorDetails = { Request: {}, Response: { body: { - status: "succeeded" - } - } + status: "succeeded", + }, + }, }, manualPaymentRefund: { Request: { @@ -418,9 +420,9 @@ export const connectorDetails = { }, Response: { body: { - status: "succeeded" - } - } + status: "succeeded", + }, + }, }, manualPaymentPartialRefund: { Request: { @@ -432,17 +434,17 @@ export const connectorDetails = { }, Response: { body: { - status: "succeeded" - } - } + status: "succeeded", + }, + }, }, SyncRefund: { Request: {}, Response: { body: { - status: "succeeded" - } - } + status: "succeeded", + }, + }, }, MandateSingleUseNo3DSAutoCapture: { Request: { @@ -522,9 +524,10 @@ export const connectorDetails = { status: 200, body: { error_code: "internalErrorOccurred", - error_message: "We cannot currently process your request. Please contact support.", + error_message: + "We cannot currently process your request. Please contact support.", status: "failed", - payment_method_id: null + payment_method_id: null, }, }, }, @@ -556,9 +559,10 @@ export const connectorDetails = { status: 200, body: { error_code: "internalErrorOccurred", - error_message: "We cannot currently process your request. Please contact support.", + error_message: + "We cannot currently process your request. Please contact support.", status: "failed", - payment_method_id: null + payment_method_id: null, }, }, }, @@ -570,7 +574,7 @@ export const connectorDetails = { }, currency: "USD", mandate_data: null, - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -587,7 +591,7 @@ export const connectorDetails = { }, currency: "USD", mandate_data: null, - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -605,7 +609,7 @@ export const connectorDetails = { currency: "USD", mandate_data: null, authentication_type: "three_ds", - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -622,7 +626,7 @@ export const connectorDetails = { }, mandate_data: null, authentication_type: "three_ds", - customer_acceptance: offileCustomerAcceptance, + customer_acceptance: customerAcceptance, }, Response: { status: 200, @@ -632,4 +636,4 @@ export const connectorDetails = { }, }, }, -} \ No newline at end of file +}; diff --git a/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js b/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js index 2caa6030c536..fd9b9d9f6e27 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js +++ b/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js @@ -5,7 +5,7 @@ import * as utils from "../PayoutUtils/Utils"; let globalState; describe("[Payout] Cards", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -13,7 +13,7 @@ describe("[Payout] Cards", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -23,37 +23,34 @@ describe("[Payout] Cards", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); context("Payout Card with Auto Fulfill", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPayoutTest( fixtures.createPayoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { @@ -62,41 +59,36 @@ describe("[Payout] Cards", () => { }); context("Payout Card with Manual Fulfill - Create Confirm", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("confirm-payout-call-with-manual-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Confirm"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPayoutTest( fixtures.createPayoutBody, - req_data, - res_data, + data, true, false, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("fulfill-payout-call-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.fulfillPayoutCallTest({}, req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.fulfillPayoutCallTest({}, data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { diff --git a/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js b/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js index 887152c3a6f5..0cb4508ded82 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js +++ b/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js @@ -6,7 +6,7 @@ let globalState; // TODO: Add test for Bank Transfer - ACH describe.skip("[Payout] [Bank Transfer - ACH]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -14,7 +14,7 @@ describe.skip("[Payout] [Bank Transfer - ACH]", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -24,7 +24,7 @@ describe.skip("[Payout] [Bank Transfer - ACH]", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -32,7 +32,7 @@ describe.skip("[Payout] [Bank Transfer - ACH]", () => { // TODO: Add test for Bank Transfer - BACS describe.skip("[Payout] [Bank Transfer - BACS]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -40,7 +40,7 @@ describe.skip("[Payout] [Bank Transfer - BACS]", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -50,14 +50,14 @@ describe.skip("[Payout] [Bank Transfer - BACS]", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); }); describe("[Payout] [Bank Transfer - SEPA]", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -65,7 +65,7 @@ describe("[Payout] [Bank Transfer - SEPA]", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -75,37 +75,33 @@ describe("[Payout] [Bank Transfer - SEPA]", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); context("[Payout] [Bank transfer - SEPA] Auto Fulfill", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; cy.createConfirmPayoutTest( fixtures.createPayoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { @@ -114,41 +110,36 @@ describe("[Payout] [Bank Transfer - SEPA]", () => { }); context("[Payout] [Bank transfer - SEPA] Manual Fulfill", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); it("confirm-payout-call-with-manual-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Confirm"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPayoutTest( fixtures.createPayoutBody, - req_data, - res_data, + data, true, false, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("fulfill-payout-call-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.fulfillPayoutCallTest({}, req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + cy.fulfillPayoutCallTest({}, data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { diff --git a/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js b/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js index edcb89d06fd4..37dc1c2cdf0f 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js +++ b/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js @@ -6,7 +6,7 @@ let globalState; let payoutBody; describe("[Payout] Saved Card", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -14,7 +14,7 @@ describe("[Payout] Saved Card", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -24,13 +24,13 @@ describe("[Payout] Saved Card", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); context("[Payout] [Card] Onboard customer prior to transaction", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails // This is needed to get customer payment methods beforeEach("seed global state", () => { @@ -42,12 +42,11 @@ describe("[Payout] Saved Card", () => { }); it("create payment method", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["SavePayoutMethod"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentMethodTest(globalState, req_data, res_data); + + cy.createPaymentMethodTest(globalState, data); }); it("list customer payment methods", () => { @@ -55,22 +54,19 @@ describe("[Payout] Saved Card", () => { }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Token"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmWithTokenPayoutTest( payoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { @@ -81,10 +77,10 @@ describe("[Payout] Saved Card", () => { context( "[Payout] [Card] Save payment method after successful transaction", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -94,22 +90,14 @@ describe("[Payout] Saved Card", () => { }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createConfirmPayoutTest( - payoutBody, - req_data, - res_data, - true, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.createConfirmPayoutTest(payoutBody, data, true, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("list customer payment methods", () => { @@ -117,22 +105,20 @@ describe("[Payout] Saved Card", () => { }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "card_pm" ]["Token"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmWithTokenPayoutTest( payoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { @@ -143,7 +129,7 @@ describe("[Payout] Saved Card", () => { }); describe("[Payout] Saved Bank transfer", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails before("seed global state", () => { cy.task("getGlobalState").then((state) => { @@ -151,7 +137,7 @@ describe("[Payout] Saved Bank transfer", () => { // Check if the connector supports card payouts (based on the connector configuration in creds) if (!globalState.get("payoutsExecution")) { - should_continue = false; + shouldContinue = false; } }); }); @@ -161,7 +147,7 @@ describe("[Payout] Saved Bank transfer", () => { }); beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -169,7 +155,7 @@ describe("[Payout] Saved Bank transfer", () => { context( "[Payout] [Bank Transfer] Onboard Customer Prior to Transaction", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach("reset payoutBody", () => { payoutBody = Cypress._.cloneDeep(fixtures.createPayoutBody); }); @@ -179,12 +165,11 @@ describe("[Payout] Saved Bank transfer", () => { }); it("create payment method", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["SavePayoutMethod"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createPaymentMethodTest(globalState, req_data, res_data); + + cy.createPaymentMethodTest(globalState, data); }); it("list customer payment methods", () => { @@ -192,22 +177,20 @@ describe("[Payout] Saved Bank transfer", () => { }); it("[Payout] [Bank transfer] [SEPA] Fulfill using Token", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Token"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmWithTokenPayoutTest( payoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { @@ -219,10 +202,10 @@ describe("[Payout] Saved Bank transfer", () => { context( "[Payout] [Bank Transfer] Save payment method after successful transaction", () => { - let should_continue = true; // variable that will be used to skip tests if a previous test fails + let shouldContinue = true; // variable that will be used to skip tests if a previous test fails beforeEach(function () { - if (!should_continue) { + if (!shouldContinue) { this.skip(); } }); @@ -232,22 +215,14 @@ describe("[Payout] Saved Bank transfer", () => { }); it("confirm-payout-call-with-auto-fulfill-test", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Fulfill"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.createConfirmPayoutTest( - payoutBody, - req_data, - res_data, - true, - true, - globalState - ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + cy.createConfirmPayoutTest(payoutBody, data, true, true, globalState); + + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("list customer payment methods", () => { @@ -255,22 +230,20 @@ describe("[Payout] Saved Bank transfer", () => { }); it("[Payout] [Bank transfer] [SEPA] Fulfill using Token", () => { - let data = utils.getConnectorDetails(globalState.get("connectorId"))[ + const data = utils.getConnectorDetails(globalState.get("connectorId"))[ "bank_transfer_pm" ]["sepa"]["Token"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmWithTokenPayoutTest( payoutBody, - req_data, - res_data, + data, true, true, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) + shouldContinue = utils.should_continue_further(data); }); it("retrieve-payout-call-test", () => { diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Commons.js b/cypress-tests/cypress/e2e/PayoutUtils/Commons.js index 5f8a580731e0..ecd85b051511 100644 --- a/cypress-tests/cypress/e2e/PayoutUtils/Commons.js +++ b/cypress-tests/cypress/e2e/PayoutUtils/Commons.js @@ -118,7 +118,6 @@ export const connectorDetails = { card: card_data, }, currency: "EUR", - payout_type: "card", }, Response: { status: 200, @@ -135,7 +134,6 @@ export const connectorDetails = { card: card_data, }, currency: "EUR", - payout_type: "card", }, Response: { status: 200, @@ -152,7 +150,6 @@ export const connectorDetails = { card: card_data, }, currency: "EUR", - payout_type: "card", }, }), SavePayoutMethod: getCustomExchange({ diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Utils.js b/cypress-tests/cypress/e2e/PayoutUtils/Utils.js index d57aac2290d1..4cd122782f21 100644 --- a/cypress-tests/cypress/e2e/PayoutUtils/Utils.js +++ b/cypress-tests/cypress/e2e/PayoutUtils/Utils.js @@ -1,3 +1,5 @@ +import { validateConfig } from "../../utils/featureFlags.js"; + import { connectorDetails as adyenConnectorDetails } from "./Adyen.js"; import { connectorDetails as adyenPlatformConnectorDetails } from "./AdyenPlatform.js"; import { connectorDetails as CommonConnectorDetails } from "./Commons.js"; @@ -11,7 +13,7 @@ const connectorDetails = { }; export function getConnectorDetails(connectorId) { - let x = mergeDetails(connectorId); + const x = mergeDetails(connectorId); return x; } @@ -50,22 +52,52 @@ function mergeConnectorDetails(source, fallback) { return merged; } -function getValueByKey(jsonObject, key) { +export function getValueByKey(jsonObject, key) { const data = typeof jsonObject === "string" ? JSON.parse(jsonObject) : jsonObject; if (data && typeof data === "object" && key in data) { + // Connector object has multiple keys + if (typeof data[key].connector_account_details === "undefined") { + const keys = Object.keys(data[key]); + + for (let i = 0; i < keys.length; i++) { + const currentItem = data[key][keys[i]]; + + if ( + Object.prototype.hasOwnProperty.call( + currentItem, + "connector_account_details" + ) + ) { + Cypress.env("MULTIPLE_CONNECTORS", { + status: true, + count: keys.length, + }); + + return currentItem; + } + } + } + return data[key]; } else { return null; } } -export const should_continue_further = (res_data) => { +export const should_continue_further = (data) => { + const resData = data.Response || {}; + const configData = validateConfig(data.Configs) || {}; + + if (typeof configData?.TRIGGER_SKIP !== "undefined") { + return !configData.TRIGGER_SKIP; + } + if ( - res_data.body.error !== undefined || - res_data.body.error_code !== undefined || - res_data.body.error_message !== undefined + typeof resData.body.error !== "undefined" || + typeof resData.body.error_code !== "undefined" || + typeof resData.body.error_message !== "undefined" ) { return false; } else { diff --git a/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js b/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js index 3037a6eb99ec..22e4b3783af1 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js +++ b/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js @@ -5,7 +5,7 @@ import * as utils from "../RoutingUtils/Utils"; let globalState; describe("Priority Based Routing Test", () => { - let should_continue = true; + let shouldContinue = true; context("Login", () => { before("seed global state", () => { @@ -52,11 +52,8 @@ describe("Priority Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = utils.getConnectorDetails("common")["priorityRouting"]; + const routing_data = [ { connector: "stripe", merchant_connector_id: globalState.get("stripeMcaId"), @@ -68,53 +65,45 @@ describe("Priority Based Routing Test", () => { ]; cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "priority", routing_data, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = utils.getConnectorDetails("common")["priorityRouting"]; + + cy.retrieveRoutingConfig(data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = utils.getConnectorDetails("common")["priorityRouting"]; + + cy.activateRoutingConfig(data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment-routing-test", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); }); @@ -141,11 +130,8 @@ describe("Priority Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = utils.getConnectorDetails("common")["priorityRouting"]; + const routing_data = [ { connector: "adyen", merchant_connector_id: globalState.get("adyenMcaId"), @@ -157,53 +143,44 @@ describe("Priority Based Routing Test", () => { ]; cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "priority", routing_data, globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = utils.getConnectorDetails("common")["priorityRouting"]; + + cy.retrieveRoutingConfig(data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + const data = utils.getConnectorDetails("common")["priorityRouting"]; + + cy.activateRoutingConfig(data, globalState); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("payment-routing-test", () => { - let data = + const data = utils.getConnectorDetails("adyen")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState ); - if (should_continue) - should_continue = utils.should_continue_further(res_data); + if (shouldContinue) shouldContinue = utils.should_continue_further(data); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); }); }); diff --git a/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js b/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js index 665afc97581e..7d7f75e3519b 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js +++ b/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js @@ -51,11 +51,8 @@ describe("Volume Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + const routing_data = [ { connector: { connector: "stripe", @@ -67,8 +64,7 @@ describe("Volume Based Routing Test", () => { cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "volume_split", routing_data, globalState @@ -76,28 +72,24 @@ describe("Volume Based Routing Test", () => { }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.retrieveRoutingConfig(data, globalState); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.activateRoutingConfig(data, globalState); }); it("payment-routing-test", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -105,20 +97,18 @@ describe("Volume Based Routing Test", () => { }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); it("create-payment-call-test-for-eps", () => { - let data = + const data = utils.getConnectorDetails("stripe")["bank_redirect_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -130,13 +120,12 @@ describe("Volume Based Routing Test", () => { }); it("Confirm bank redirect", () => { - let data = utils.getConnectorDetails("stripe")["bank_redirect_pm"]["eps"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = + utils.getConnectorDetails("stripe")["bank_redirect_pm"]["eps"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -144,8 +133,8 @@ describe("Volume Based Routing Test", () => { it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, @@ -177,11 +166,8 @@ describe("Volume Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + const routing_data = [ { connector: { connector: "adyen", @@ -193,8 +179,7 @@ describe("Volume Based Routing Test", () => { cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "volume_split", routing_data, globalState @@ -202,28 +187,24 @@ describe("Volume Based Routing Test", () => { }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.retrieveRoutingConfig(data, globalState); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.activateRoutingConfig(data, globalState); }); it("payment-routing-test-for-card", () => { - let data = + const data = utils.getConnectorDetails("adyen")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -231,18 +212,16 @@ describe("Volume Based Routing Test", () => { }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); it("create-payment-call-test-for-eps", () => { - let data = + const data = utils.getConnectorDetails("adyen")["bank_redirect_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -254,13 +233,12 @@ describe("Volume Based Routing Test", () => { }); it("Confirm bank redirect", () => { - let data = utils.getConnectorDetails("adyen")["bank_redirect_pm"]["eps"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = + utils.getConnectorDetails("adyen")["bank_redirect_pm"]["eps"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -268,8 +246,8 @@ describe("Volume Based Routing Test", () => { it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, diff --git a/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js b/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js index c98f34a55bb5..304668752cd1 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js +++ b/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js @@ -51,11 +51,8 @@ describe("Rule Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = { + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + const routing_data = { defaultSelection: { type: "priority", data: [], @@ -121,8 +118,7 @@ describe("Rule Based Routing Test", () => { cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "advanced", routing_data, globalState @@ -130,28 +126,24 @@ describe("Rule Based Routing Test", () => { }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.retrieveRoutingConfig(data, globalState); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + + cy.activateRoutingConfig(data, globalState); }); it("payment-routing-test for card", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createConfirmPaymentTest( fixtures.createConfirmPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -159,18 +151,16 @@ describe("Rule Based Routing Test", () => { }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); it("create-payment-routing-test for bank redirect", () => { - let data = + const data = utils.getConnectorDetails("adyen")["bank_redirect_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "three_ds", "automatic", globalState @@ -178,14 +168,12 @@ describe("Rule Based Routing Test", () => { }); it("Confirm bank redirect", () => { - let data = + const data = utils.getConnectorDetails("adyen")["bank_redirect_pm"]["ideal"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmBankRedirectCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -193,8 +181,8 @@ describe("Rule Based Routing Test", () => { it("Handle bank redirect redirection", () => { // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated - let expected_redirection = fixtures.confirmBody["return_url"]; - let payment_method_type = globalState.get("paymentMethodType"); + const expected_redirection = fixtures.confirmBody["return_url"]; + const payment_method_type = globalState.get("paymentMethodType"); cy.handleBankRedirectRedirection( globalState, payment_method_type, @@ -227,11 +215,8 @@ describe("Rule Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = { + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + const routing_data = { defaultSelection: { type: "priority", data: [ @@ -275,8 +260,7 @@ describe("Rule Based Routing Test", () => { cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "advanced", routing_data, globalState @@ -284,28 +268,24 @@ describe("Rule Based Routing Test", () => { }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.retrieveRoutingConfig(data, globalState); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + + cy.activateRoutingConfig(data, globalState); }); it("create-payment-call-test-with-USD", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -313,31 +293,23 @@ describe("Rule Based Routing Test", () => { }); it("Confirm No 3DS", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); it("create-payment-call-test-with-EUR", () => { - let data = utils.getConnectorDetails("adyen")["card_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + const data = + utils.getConnectorDetails("adyen")["card_pm"]["PaymentIntent"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -345,21 +317,14 @@ describe("Rule Based Routing Test", () => { }); it("Confirm No 3DS", () => { - let data = + const data = utils.getConnectorDetails("adyen")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); }); @@ -389,11 +354,8 @@ describe("Rule Based Routing Test", () => { }); it("add-routing-config", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = { + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + const routing_data = { defaultSelection: { type: "priority", data: [], @@ -453,8 +415,7 @@ describe("Rule Based Routing Test", () => { cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "advanced", routing_data, globalState @@ -462,28 +423,24 @@ describe("Rule Based Routing Test", () => { }); it("retrieve-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["volumeBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.retrieveRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["volumeBasedRouting"]; + + cy.retrieveRoutingConfig(data, globalState); }); it("activate-routing-call-test", () => { - let data = utils.getConnectorDetails("common")["ruleBasedRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = utils.getConnectorDetails("common")["ruleBasedRouting"]; + + cy.activateRoutingConfig(data, globalState); }); it("create-payment-call-test-with-amount-10", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -491,32 +448,23 @@ describe("Rule Based Routing Test", () => { }); it("Confirm No 3DS", () => { - let data = + const data = utils.getConnectorDetails("stripe")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); it("create-payment-call-test-with-amount-9", () => { - let data = + const data = utils.getConnectorDetails("adyen")["card_pm"]["PaymentIntent"]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -524,20 +472,13 @@ describe("Rule Based Routing Test", () => { }); it("Confirm No 3DS", () => { - let data = + const data = utils.getConnectorDetails("adyen")["card_pm"]["No3DSAutoCapture"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); it("retrieve-payment-call-test", () => { - cy.retrievePaymentCallTest(globalState); + cy.retrievePaymentCallTest(globalState, null); }); }); } diff --git a/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js b/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js index 79b3d3cba7c4..74c02d7ac9fd 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js +++ b/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js @@ -42,7 +42,7 @@ describe("Auto Retries & Step Up 3DS", () => { context("Auto Retries", () => { context("[Config: enable] Auto retries", () => { it("Enable auto retries", () => { - cy.updateConfig('autoRetry', fixtures.configs.gsm, globalState, "true"); + cy.updateConfig("autoRetry", globalState, "true"); }); context("Max auto retries", () => { @@ -59,11 +59,9 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Add routing config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = + utils.getConnectorDetails("common")["priorityRouting"]; + const routing_data = [ { connector: "adyen", merchant_connector_id: globalState.get("adyenMcaId"), @@ -79,8 +77,7 @@ describe("Auto Retries & Step Up 3DS", () => { ]; cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "priority", routing_data, globalState @@ -88,36 +85,29 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Activate routing config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = + utils.getConnectorDetails("common")["priorityRouting"]; + + cy.activateRoutingConfig(data, globalState); }); }); context("Max auto retries = 2", () => { const max_auto_retries = 2; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -125,16 +115,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "BluesnapConfirm" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -143,6 +131,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -153,26 +142,19 @@ describe("Auto Retries & Step Up 3DS", () => { context("Max auto retries = 1", () => { const max_auto_retries = 1; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -180,16 +162,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "StripeConfirmSuccess" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -198,6 +178,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -207,26 +188,19 @@ describe("Auto Retries & Step Up 3DS", () => { context("Max auto retries = 0", () => { const max_auto_retries = 0; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -234,16 +208,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "AdyenConfirmFail" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -252,6 +224,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -273,11 +246,9 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Add routing config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - - let routing_data = [ + const data = + utils.getConnectorDetails("common")["priorityRouting"]; + const routing_data = [ { connector: "stripe", merchant_connector_id: globalState.get("stripeMcaId"), @@ -293,8 +264,7 @@ describe("Auto Retries & Step Up 3DS", () => { ]; cy.addRoutingConfig( fixtures.routingConfigBody, - req_data, - res_data, + data, "priority", routing_data, globalState @@ -302,36 +272,29 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Activate routing config", () => { - let data = utils.getConnectorDetails("common")["priorityRouting"]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.activateRoutingConfig(req_data, res_data, globalState); + const data = + utils.getConnectorDetails("common")["priorityRouting"]; + + cy.activateRoutingConfig(data, globalState); }); }); context("Max auto retries = 2", () => { const max_auto_retries = 2; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -339,16 +302,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "BluesnapConfirm" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -357,6 +318,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -367,26 +329,19 @@ describe("Auto Retries & Step Up 3DS", () => { context("Max auto retries = 1", () => { const max_auto_retries = 1; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -394,16 +349,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "AdyenConfirm" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -412,6 +365,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -422,26 +376,19 @@ describe("Auto Retries & Step Up 3DS", () => { context("Max auto retries = 0", () => { const max_auto_retries = 0; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); context("Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -449,16 +396,14 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "StripeConfirmFail" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.confirmCallTest( fixtures.confirmBody, - req_data, - res_data, + data, true, globalState ); @@ -467,6 +412,7 @@ describe("Auto Retries & Step Up 3DS", () => { it("Payment retrieve call", () => { cy.retrievePaymentCallTest( globalState, + null, true, max_auto_retries + 1 ); @@ -483,32 +429,25 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("[Config: enable] Step up for Stripe", () => { - cy.updateConfig('stepUp',fixtures.configs.step_up, globalState, '["stripe"]'); + cy.updateConfig("stepUp", globalState, '["stripe"]'); }); }); context("Make Payment", () => { const max_auto_retries = 1; it("Update max auto retries", () => { - cy.updateConfig( - 'maxRetries', - fixtures.configs.max_auto_retries, - globalState, - `${max_auto_retries}` - ); + cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); }); it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -516,23 +455,21 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "StripeConfirm3DS" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("Payment retrieve call", () => { - cy.retrievePaymentCallTest(globalState, true, max_auto_retries + 1); + cy.retrievePaymentCallTest( + globalState, + null, + true, + max_auto_retries + 1 + ); }); }); }); @@ -540,8 +477,8 @@ describe("Auto Retries & Step Up 3DS", () => { context("[Config: disable] Auto retries", () => { it("[Config: disable] Auto retries", () => { - cy.updateConfig('autoRetry', fixtures.configs.gsm, globalState, "false"); - }); + cy.updateConfig("autoRetry", globalState, "false"); + }); it("[Config: disable] Step up GSM", () => { cy.updateGsmConfig(fixtures.gsmBody.gsm_update, globalState, false); @@ -550,16 +487,14 @@ describe("Auto Retries & Step Up 3DS", () => { context("Make payment", () => { context("[Failed] Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -567,38 +502,29 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "StripeConfirmFail" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("Payment retrieve call", () => { - cy.retrievePaymentCallTest(globalState, true); + cy.retrievePaymentCallTest(globalState, null, true); }); }); context("[Succeeded] Make payment", () => { it("Payment create call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "PaymentIntent" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; + cy.createPaymentIntentTest( fixtures.createPaymentBody, - req_data, - res_data, + data, "no_three_ds", "automatic", globalState @@ -606,23 +532,16 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("Payment confirm call", () => { - let data = + const data = utils.getConnectorDetails("autoretries")["card_pm"][ "StripeConfirmSuccess" ]; - let req_data = data["Request"]; - let res_data = data["Response"]; - cy.confirmCallTest( - fixtures.confirmBody, - req_data, - res_data, - true, - globalState - ); + + cy.confirmCallTest(fixtures.confirmBody, data, true, globalState); }); it("Payment retrieve call", () => { - cy.retrievePaymentCallTest(globalState, true); + cy.retrievePaymentCallTest(globalState, null, true); }); }); }); diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Commons.js b/cypress-tests/cypress/e2e/RoutingUtils/Commons.js index 7723ec7749b3..1131f5e671ee 100644 --- a/cypress-tests/cypress/e2e/RoutingUtils/Commons.js +++ b/cypress-tests/cypress/e2e/RoutingUtils/Commons.js @@ -51,11 +51,4 @@ export const connectorDetails = { body: {}, }, }, - jwt: { - Request: {}, - Response: { - status: 200, - body: {}, - }, - }, }; diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Utils.js b/cypress-tests/cypress/e2e/RoutingUtils/Utils.js index ad92999c2874..a661c5d49924 100644 --- a/cypress-tests/cypress/e2e/RoutingUtils/Utils.js +++ b/cypress-tests/cypress/e2e/RoutingUtils/Utils.js @@ -11,7 +11,7 @@ const connectorDetails = { }; export const getConnectorDetails = (connectorId) => { - let x = getValueByKey(connectorDetails, connectorId); + const x = getValueByKey(connectorDetails, connectorId); return x; }; @@ -26,11 +26,13 @@ function getValueByKey(jsonObject, key) { } } -export const should_continue_further = (res_data) => { +export const should_continue_further = (data) => { + const resData = data.Response || {}; + if ( - res_data.body.error !== undefined || - res_data.body.error_code !== undefined || - res_data.body.error_message !== undefined + typeof resData.body.error !== "undefined" || + typeof resData.body.error_code !== "undefined" || + typeof resData.body.error_message !== "undefined" ) { return false; } else { diff --git a/cypress-tests/cypress/fixtures/create-ntid-mit.json b/cypress-tests/cypress/fixtures/create-ntid-mit.json index 61e86828338b..0673220b54d4 100644 --- a/cypress-tests/cypress/fixtures/create-ntid-mit.json +++ b/cypress-tests/cypress/fixtures/create-ntid-mit.json @@ -1,49 +1,48 @@ { - "amount": 999, - "currency": "USD", - "confirm": true, - "payment_method": "card", - "return_url": "https://hyperswitch.io", - "email": "example@email.com", - "recurring_details": { - "type": "network_transaction_id_and_card_details", - "data": { - "card_number": "4242424242424242", - "card_exp_month": "11", - "card_exp_year": "2050", - "card_holder_name": "joseph Doe", - "network_transaction_id": "MCC5ZRGMI0925" - } - }, - "off_session": true, - "billing": { - "address": { - "first_name": "John", - "last_name": "Doe", - "line1": "1467", - "line2": "Harrison Street", - "line3": "Harrison Street", - "city": "San Fransico", - "state": "California", - "zip": "94122", - "country": "US" - }, - "phone": { - "number": "9123456789", - "country_code": "+91" - } + "amount": 999, + "currency": "USD", + "confirm": true, + "payment_method": "card", + "return_url": "https://hyperswitch.io", + "email": "example@email.com", + "recurring_details": { + "type": "network_transaction_id_and_card_details", + "data": { + "card_number": "4242424242424242", + "card_exp_month": "11", + "card_exp_year": "2050", + "card_holder_name": "joseph Doe", + "network_transaction_id": "MCC5ZRGMI0925" + } + }, + "off_session": true, + "billing": { + "address": { + "first_name": "John", + "last_name": "Doe", + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "city": "San Fransico", + "state": "California", + "zip": "94122", + "country": "US" }, - "browser_info": { - "ip_address": "129.0.0.1", - "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", - "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", - "language": "en-US", - "color_depth": 30, - "screen_height": 1117, - "screen_width": 1728, - "time_zone": -330, - "java_enabled": true, - "java_script_enabled": true + "phone": { + "number": "9123456789", + "country_code": "+91" } + }, + "browser_info": { + "ip_address": "129.0.0.1", + "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", + "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "language": "en-US", + "color_depth": 30, + "screen_height": 1117, + "screen_width": 1728, + "time_zone": -330, + "java_enabled": true, + "java_script_enabled": true } - \ No newline at end of file +} diff --git a/cypress-tests/cypress/support/commands.js b/cypress-tests/cypress/support/commands.js index 5a6e1b4783e4..f3ce856fe38a 100644 --- a/cypress-tests/cypress/support/commands.js +++ b/cypress-tests/cypress/support/commands.js @@ -26,6 +26,7 @@ // commands.js or your custom support file import { defaultErrorHandler, getValueByKey } from "../e2e/PaymentUtils/Utils"; +import { execConfig, validateConfig } from "../utils/featureFlags"; import * as RequestBodyUtils from "../utils/RequestBodyUtils"; import { handleRedirection } from "./redirectionHandler"; @@ -166,23 +167,30 @@ Cypress.Commands.add( Cypress.Commands.add( "createBusinessProfileTest", - (createBusinessProfile, globalState) => { + (createBusinessProfile, globalState, profile_prefix = "profile") => { + const api_key = globalState.get("adminApiKey"); + const base_url = globalState.get("baseUrl"); + const connector_id = globalState.get("connectorId"); const merchant_id = globalState.get("merchantId"); - const randomProfileName = `profile_${Math.random().toString(36).substring(7)}`; - createBusinessProfile.profile_name = randomProfileName; + const profile_name = `${connector_id}_${profile_prefix}_${Math.random().toString(36).substring(7)}`; + const url = `${base_url}/account/${merchant_id}/business_profile`; + + createBusinessProfile.profile_name = profile_name; + cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/account/${merchant_id}/business_profile`, + url: url, headers: { Accept: "application/json", "Content-Type": "application/json", - "api-key": globalState.get("adminApiKey"), + "api-key": api_key, }, body: createBusinessProfile, failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - globalState.set("profileId", response.body.profile_id); + globalState.set(`${profile_prefix}Id`, response.body.profile_id); + if (response.status === 200) { expect(response.body.profile_id).to.not.to.be.null; } else { @@ -376,16 +384,21 @@ Cypress.Commands.add( ( connectorType, createConnectorBody, - payment_methods_enabled, + paymentMethodsEnabled, globalState, connectorName, - connectorLabel + connectorLabel, + profilePrefix = "profile", + mcaPrefix = "merchantConnector" ) => { const merchantId = globalState.get("merchantId"); + const profileId = globalState.get(`${profilePrefix}Id`); + + createConnectorBody.profile_id = profileId; createConnectorBody.connector_type = connectorType; createConnectorBody.connector_name = connectorName; createConnectorBody.connector_label = connectorLabel; - createConnectorBody.payment_methods_enabled = payment_methods_enabled; + createConnectorBody.payment_methods_enabled = paymentMethodsEnabled; // readFile is used to read the contents of the file and it always returns a promise ([Object Object]) due to its asynchronous nature // it is best to use then() to handle the response within the same block of code cy.readFile(globalState.get("connectorAuthFilePath")).then( @@ -412,7 +425,7 @@ Cypress.Commands.add( if (response.status === 200) { expect(connectorName).to.equal(response.body.connector_name); globalState.set( - "merchantConnectorId", + `${mcaPrefix}Id`, response.body.merchant_connector_id ); } else { @@ -437,21 +450,31 @@ Cypress.Commands.add( connectorType, createConnectorBody, payment_methods_enabled, - globalState + globalState, + profile_prefix = "profile", + mca_prefix = "merchantConnector" ) => { - const merchantId = globalState.get("merchantId"); + const api_key = globalState.get("adminApiKey"); + const base_url = globalState.get("baseUrl"); + const connector_id = globalState.get("connectorId"); + const merchant_id = globalState.get("merchantId"); + const profile_id = globalState.get(`${profile_prefix}Id`); + const url = `${base_url}/account/${merchant_id}/connectors`; + createConnectorBody.connector_type = connectorType; - createConnectorBody.profile_id = globalState.get("profileId"); - createConnectorBody.connector_name = globalState.get("connectorId"); + createConnectorBody.profile_id = profile_id; + createConnectorBody.connector_name = connector_id; createConnectorBody.payment_methods_enabled = payment_methods_enabled; + // readFile is used to read the contents of the file and it always returns a promise ([Object Object]) due to its asynchronous nature // it is best to use then() to handle the response within the same block of code cy.readFile(globalState.get("connectorAuthFilePath")).then( (jsonContent) => { const authDetails = getValueByKey( JSON.stringify(jsonContent), - globalState.get("connectorId") + connector_id ); + createConnectorBody.connector_account_details = authDetails.connector_account_details; @@ -464,11 +487,11 @@ Cypress.Commands.add( cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/account/${merchantId}/connectors`, + url: url, headers: { - "Content-Type": "application/json", Accept: "application/json", - "api-key": globalState.get("adminApiKey"), + "Content-Type": "application/json", + "api-key": api_key, }, body: createConnectorBody, failOnStatusCode: false, @@ -479,9 +502,8 @@ Cypress.Commands.add( expect(globalState.get("connectorId")).to.equal( response.body.connector_name ); - globalState.set("profileId", response.body.profile_id); globalState.set( - "merchantConnectorId", + `${mca_prefix}Id`, response.body.merchant_connector_id ); } else { @@ -504,7 +526,7 @@ Cypress.Commands.add( "createPayoutConnectorCallTest", (connectorType, createConnectorBody, globalState) => { const merchantId = globalState.get("merchantId"); - let connectorName = globalState.get("connectorId"); + const connectorName = globalState.get("connectorId"); createConnectorBody.connector_type = connectorType; createConnectorBody.connector_name = connectorName; createConnectorBody.connector_type = "payout_processor"; @@ -514,7 +536,7 @@ Cypress.Commands.add( // it is best to use then() to handle the response within the same block of code cy.readFile(globalState.get("connectorAuthFilePath")).then( (jsonContent) => { - let authDetails = getValueByKey( + const authDetails = getValueByKey( JSON.stringify(jsonContent), `${connectorName}_payout` ); @@ -621,18 +643,22 @@ Cypress.Commands.add("connectorDeleteCall", (globalState) => { Cypress.Commands.add( "connectorUpdateCall", (connectorType, updateConnectorBody, globalState) => { - const merchant_id = globalState.get("merchantId"); + const api_key = globalState.get("adminApiKey"); + const base_url = globalState.get("baseUrl"); const connector_id = globalState.get("connectorId"); + const merchant_id = globalState.get("merchantId"); const merchant_connector_id = globalState.get("merchantConnectorId"); + const url = `${base_url}/account/${merchant_id}/connectors/${merchant_connector_id}`; + updateConnectorBody.connector_type = connectorType; cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/account/${merchant_id}/connectors/${merchant_connector_id}`, + url: url, headers: { Accept: "application/json", "Content-Type": "application/json", - "api-key": globalState.get("adminApiKey"), + "api-key": api_key, "x-merchant-id": merchant_id, }, body: updateConnectorBody, @@ -804,7 +830,7 @@ Cypress.Commands.add("customerDeleteCall", (globalState) => { Cypress.Commands.add( "paymentMethodListTestLessThanEqualToOnePaymentMethod", - (res_data, globalState) => { + (resData, globalState) => { cy.request({ method: "GET", url: `${globalState.get("baseUrl")}/account/payment_methods?client_secret=${globalState.get("clientSecret")}`, @@ -819,20 +845,78 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); if (response.status === 200) { expect(response.body).to.have.property("currency"); - if (res_data["payment_methods"].length == 1) { + if (resData["payment_methods"].length == 1) { function getPaymentMethodType(obj) { return obj["payment_methods"][0]["payment_method_types"][0][ "payment_method_type" ]; } - expect(getPaymentMethodType(res_data)).to.equal( + expect(getPaymentMethodType(resData)).to.equal( getPaymentMethodType(response.body) ); } else { expect(0).to.equal(response.body["payment_methods"].length); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); + } + }); + } +); + +Cypress.Commands.add( + "paymentMethodListTestWithRequiredFields", + (data, globalState) => { + const apiKey = globalState.get("publishableKey"); + const baseUrl = globalState.get("baseUrl"); + const clientSecret = globalState.get("clientSecret"); + const url = `${baseUrl}/account/payment_methods?client_secret=${clientSecret}`; + + cy.request({ + method: "GET", + url: url, + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": apiKey, + }, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + expect(response.headers["content-type"]).to.include("application/json"); + + if (response.status === 200) { + const responsePaymentMethods = response.body["payment_methods"]; + const responseRequiredFields = + responsePaymentMethods[0]["payment_method_types"][0][ + "required_fields" + ]; + + const expectedRequiredFields = + data["payment_methods"][0]["payment_method_types"][0][ + "required_fields" + ]; + + Object.keys(expectedRequiredFields).forEach((key) => { + const expectedField = expectedRequiredFields[key]; + const responseField = responseRequiredFields[key]; + + expect(responseField).to.exist; + expect(responseField.required_field).to.equal( + expectedField.required_field + ); + expect(responseField.display_name).to.equal( + expectedField.display_name + ); + expect(responseField.field_type).to.deep.equal( + expectedField.field_type + ); + expect(responseField.value).to.equal(expectedField.value); + }); + } else { + throw new Error( + `List payment methods failed with status code "${response.status}" and error message "${response.body.error.message}"` + ); } }); } @@ -840,7 +924,7 @@ Cypress.Commands.add( Cypress.Commands.add( "paymentMethodListTestTwoConnectorsForOnePaymentMethodCredit", - (res_data, globalState) => { + (resData, globalState) => { cy.request({ method: "GET", url: `${globalState.get("baseUrl")}/account/payment_methods?client_secret=${globalState.get("clientSecret")}`, @@ -855,7 +939,7 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); if (response.status === 200) { expect(response.body).to.have.property("currency"); - if (res_data["payment_methods"].length > 0) { + if (resData["payment_methods"].length > 0) { function getPaymentMethodType(obj) { return obj["payment_methods"][0]["payment_method_types"][0][ "card_networks" @@ -863,8 +947,8 @@ Cypress.Commands.add( .slice() .sort(); } - let config_payment_method_type = getPaymentMethodType(res_data); - let response_payment_method_type = getPaymentMethodType( + const config_payment_method_type = getPaymentMethodType(resData); + const response_payment_method_type = getPaymentMethodType( response.body ); for (let i = 0; i < response_payment_method_type.length; i++) { @@ -876,13 +960,13 @@ Cypress.Commands.add( expect(0).to.equal(response.body["payment_methods"].length); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } ); -Cypress.Commands.add("sessionTokenCall", (apiKeyCreateBody, globalState) => { +Cypress.Commands.add("sessionTokenCall", (globalState, sessionTokenBody) => { cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments/session_tokens`, @@ -902,30 +986,40 @@ Cypress.Commands.add( "createPaymentIntentTest", ( createPaymentBody, - req_data, - res_data, + data, authentication_type, capture_method, globalState ) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + if ( !createPaymentBody || typeof createPaymentBody !== "object" || - !req_data.currency + !reqData.currency ) { throw new Error( "Invalid parameters provided to createPaymentIntentTest command" ); } - for (const key in req_data) { - createPaymentBody[key] = req_data[key]; + const config_info = execConfig(validateConfig(configs)); + const profile_id = globalState.get(config_info.profile_id); + + for (const key in reqData) { + createPaymentBody[key] = reqData[key]; } createPaymentBody.authentication_type = authentication_type; createPaymentBody.capture_method = capture_method; createPaymentBody.customer_id = globalState.get("customerId"); - createPaymentBody.profile_id = globalState.get("profileId"); + createPaymentBody.profile_id = profile_id; + globalState.set("paymentAmount", createPaymentBody.amount); + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments`, @@ -941,16 +1035,16 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); - if (res_data.status === 200) { + if (resData.status === 200) { expect(response.body).to.have.property("client_secret"); const clientSecret = response.body.client_secret; globalState.set("clientSecret", clientSecret); globalState.set("paymentID", response.body.payment_id); cy.log(clientSecret); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal( + for (const key in resData.body) { + expect(resData.body[key]).to.equal( response.body[key], - `Expected ${res_data.body[key]} but got ${response.body[key]}` + `Expected ${resData.body[key]} but got ${response.body[key]}` ); } expect(response.body.payment_id, "payment_id").to.not.be.null; @@ -1012,7 +1106,7 @@ Cypress.Commands.add( expect(response.body.connector_mandate_id, "connector_mandate_id").to.be .null; } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1067,52 +1161,51 @@ Cypress.Commands.add("paymentMethodsCallTest", (globalState) => { }); }); -Cypress.Commands.add( - "createPaymentMethodTest", - (globalState, req_data, res_data) => { - req_data.customer_id = globalState.get("customerId"); - const merchant_id = globalState.get("merchantId"); +Cypress.Commands.add("createPaymentMethodTest", (globalState, data) => { + const { Request: reqData, Response: resData } = data || {}; - cy.request({ - method: "POST", - url: `${globalState.get("baseUrl")}/payment_methods`, - headers: { - "Content-Type": "application/json", - Accept: "application/json", - "api-key": globalState.get("apiKey"), - }, - body: req_data, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); + reqData.customer_id = globalState.get("customerId"); + const merchant_id = globalState.get("merchantId"); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - expect(response.body.client_secret, "client_secret").to.include( - "_secret_" - ).and.to.not.be.null; - expect(response.body.payment_method_id, "payment_method_id").to.not.be - .null; - expect(response.body.merchant_id, "merchant_id").to.equal(merchant_id); - expect(req_data.payment_method_type, "payment_method_type").to.equal( - response.body.payment_method_type - ); - expect(req_data.payment_method, "payment_method").to.equal( - response.body.payment_method - ); - expect(response.body.last_used_at, "last_used_at").to.not.be.null; - expect(req_data.customer_id, "customer_id").to.equal( - response.body.customer_id - ); - globalState.set("paymentMethodId", response.body.payment_method_id); - } else { - defaultErrorHandler(response, res_data); - } - }); - } -); + cy.request({ + method: "POST", + url: `${globalState.get("baseUrl")}/payment_methods`, + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "api-key": globalState.get("apiKey"), + }, + body: reqData, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + expect(response.body.client_secret, "client_secret").to.include( + "_secret_" + ).and.to.not.be.null; + expect(response.body.payment_method_id, "payment_method_id").to.not.be + .null; + expect(response.body.merchant_id, "merchant_id").to.equal(merchant_id); + expect(reqData.payment_method_type, "payment_method_type").to.equal( + response.body.payment_method_type + ); + expect(reqData.payment_method, "payment_method").to.equal( + response.body.payment_method + ); + expect(response.body.last_used_at, "last_used_at").to.not.be.null; + expect(reqData.customer_id, "customer_id").to.equal( + response.body.customer_id + ); + globalState.set("paymentMethodId", response.body.payment_method_id); + } else { + defaultErrorHandler(response, resData); + } + }); +}); -Cypress.Commands.add("deletePaymentMethodTest", (globalState, res_data) => { +Cypress.Commands.add("deletePaymentMethodTest", (globalState, resData) => { const payment_method_id = globalState.get("paymentMethodId"); cy.request({ method: "DELETE", @@ -1130,7 +1223,7 @@ Cypress.Commands.add("deletePaymentMethodTest", (globalState, res_data) => { expect(response.body.payment_method_id).to.equal(payment_method_id); expect(response.body.deleted).to.be.true; } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); }); @@ -1162,19 +1255,37 @@ Cypress.Commands.add("setDefaultPaymentMethodTest", (globalState) => { Cypress.Commands.add( "confirmCallTest", - (confirmBody, req_data, res_data, confirm, globalState) => { + (confirmBody, data, confirm, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const apiKey = globalState.get("publishableKey"); + const baseUrl = globalState.get("baseUrl"); + const configInfo = execConfig(validateConfig(configs)); + const merchantConnectorId = globalState.get( + configInfo.merchant_connector_id + ); const paymentIntentID = globalState.get("paymentID"); - confirmBody.confirm = confirm; + const profileId = globalState.get(configInfo.profile_id); + const url = `${baseUrl}/payments/${paymentIntentID}/confirm`; + confirmBody.client_secret = globalState.get("clientSecret"); - for (const key in req_data) { - confirmBody[key] = req_data[key]; + confirmBody.confirm = confirm; + confirmBody.profile_id = profileId; + + for (const key in reqData) { + confirmBody[key] = reqData[key]; } + cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/payments/${paymentIntentID}/confirm`, + url: url, headers: { "Content-Type": "application/json", - "api-key": globalState.get("publishableKey"), + "api-key": apiKey, }, failOnStatusCode: false, body: confirmBody, @@ -1192,12 +1303,13 @@ Cypress.Commands.add( ); expect(response.body.payment_method_data, "payment_method_data").to.not .be.empty; - expect(globalState.get("merchantConnectorId"), "connector_id").to.equal( + expect(merchantConnectorId, "connector_id").to.equal( response.body.merchant_connector_id ); expect(response.body.customer, "customer").to.not.be.empty; expect(response.body.billing, "billing_address").to.not.be.empty; - expect(response.body.profile_id, "profile_id").to.not.be.null; + expect(response.body.profile_id, "profile_id").to.equal(profileId).and + .to.not.be.null; if (response.body.capture_method === "automatic") { if (response.body.authentication_type === "three_ds") { @@ -1208,14 +1320,14 @@ Cypress.Commands.add( "nextActionUrl", response.body.next_action.redirect_to_url ); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } @@ -1233,14 +1345,14 @@ Cypress.Commands.add( "nextActionUrl", response.body.next_action.redirect_to_url ); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } @@ -1255,7 +1367,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1263,14 +1375,24 @@ Cypress.Commands.add( Cypress.Commands.add( "confirmBankRedirectCallTest", - (confirmBody, req_data, res_data, confirm, globalState) => { - const paymentIntentId = globalState.get("paymentID"); + (confirmBody, data, confirm, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); const connectorId = globalState.get("connectorId"); - for (const key in req_data) { - confirmBody[key] = req_data[key]; + const paymentIntentId = globalState.get("paymentID"); + const profile_id = globalState.get(config_info.profile_id); + + for (const key in reqData) { + confirmBody[key] = reqData[key]; } - confirmBody.confirm = confirm; confirmBody.client_secret = globalState.get("clientSecret"); + confirmBody.confirm = confirm; + confirmBody.profile_id = profile_id; cy.request({ method: "POST", @@ -1316,7 +1438,7 @@ Cypress.Commands.add( } } else if (response.body.status === "failed") { expect(response.body.error_code).to.equal( - res_data.body.error_code + resData.body.error_code ); } } else { @@ -1349,7 +1471,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1357,13 +1479,24 @@ Cypress.Commands.add( Cypress.Commands.add( "confirmBankTransferCallTest", - (confirmBody, req_data, res_data, confirm, globalState) => { + (confirmBody, data, confirm, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); const paymentIntentID = globalState.get("paymentID"); - for (const key in req_data) { - confirmBody[key] = req_data[key]; + const profile_id = globalState.get(config_info.profile_id); + + for (const key in reqData) { + confirmBody[key] = reqData[key]; } - confirmBody.confirm = confirm; confirmBody.client_secret = globalState.get("clientSecret"); + confirmBody.confirm = confirm; + confirmBody.profile_id = globalState.get(profile_id); + globalState.set("paymentMethodType", confirmBody.payment_method_type); cy.request({ @@ -1419,7 +1552,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1427,13 +1560,24 @@ Cypress.Commands.add( Cypress.Commands.add( "confirmUpiCall", - (confirmBody, req_data, res_data, confirm, globalState) => { + (confirmBody, data, confirm, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); const paymentId = globalState.get("paymentID"); - for (const key in req_data) { - confirmBody[key] = req_data[key]; + const profile_id = globalState.get(config_info.profile_id); + + for (const key in reqData) { + confirmBody[key] = reqData[key]; } - confirmBody.confirm = confirm; confirmBody.client_secret = globalState.get("clientSecret"); + confirmBody.confirm = confirm; + confirmBody.profile_id = profile_id; + globalState.set("paymentMethodType", confirmBody.payment_method_type); cy.request({ @@ -1476,7 +1620,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1486,19 +1630,31 @@ Cypress.Commands.add( "createConfirmPaymentTest", ( createConfirmPaymentBody, - req_data, - res_data, + data, authentication_type, capture_method, globalState ) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); + const merchant_connector_id = globalState.get( + config_info.merchant_connector_id + ); + const profile_id = globalState.get(config_info.profile_id); + createConfirmPaymentBody.authentication_type = authentication_type; createConfirmPaymentBody.capture_method = capture_method; createConfirmPaymentBody.customer_id = globalState.get("customerId"); - createConfirmPaymentBody.profile_id = globalState.get("profileId"); - for (const key in req_data) { - createConfirmPaymentBody[key] = req_data[key]; + createConfirmPaymentBody.profile_id = profile_id; + for (const key in reqData) { + createConfirmPaymentBody[key] = reqData[key]; } + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments`, @@ -1510,8 +1666,11 @@ Cypress.Commands.add( body: createConfirmPaymentBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); + globalState.set("clientSecret", response.body.client_secret); + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { globalState.set("paymentAmount", createConfirmPaymentBody.amount); globalState.set("paymentID", response.body.payment_id); @@ -1524,12 +1683,13 @@ Cypress.Commands.add( expect(response.body.payment_method_data, "payment_method_data").to.not .be.empty; expect(response.body.merchant_connector_id, "connector_id").to.equal( - globalState.get("merchantConnectorId") + merchant_connector_id ); expect(response.body.customer, "customer").to.not.be.empty; expect(response.body.billing, "billing_address").to.not.be.empty; expect(response.body.profile_id, "profile_id").to.not.be.null; expect(response.body).to.have.property("status"); + if (response.body.capture_method === "automatic") { if (response.body.authentication_type === "three_ds") { expect(response.body) @@ -1539,14 +1699,14 @@ Cypress.Commands.add( "nextActionUrl", response.body.next_action.redirect_to_url ); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } @@ -1564,14 +1724,14 @@ Cypress.Commands.add( "nextActionUrl", response.body.next_action.redirect_to_url ); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.deep.equal( + for (const key in resData.body) { + expect(resData.body[key], [key]).to.deep.equal( response.body[key] ); } @@ -1582,7 +1742,7 @@ Cypress.Commands.add( } } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1591,16 +1751,30 @@ Cypress.Commands.add( // This is consequent saved card payment confirm call test(Using payment token) Cypress.Commands.add( "saveCardConfirmCallTest", - (saveCardConfirmBody, req_data, res_data, globalState) => { + (saveCardConfirmBody, data, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); + const merchant_connector_id = globalState.get( + config_info.merchant_connector_id + ); const paymentIntentID = globalState.get("paymentID"); - if (req_data.setup_future_usage === "on_session") { - saveCardConfirmBody.card_cvc = req_data.payment_method_data.card.card_cvc; + const profile_id = globalState.get(config_info.profile_id); + + if (reqData.setup_future_usage === "on_session") { + saveCardConfirmBody.card_cvc = reqData.payment_method_data.card.card_cvc; } - saveCardConfirmBody.payment_token = globalState.get("paymentToken"); saveCardConfirmBody.client_secret = globalState.get("clientSecret"); - for (const key in req_data) { - saveCardConfirmBody[key] = req_data[key]; + saveCardConfirmBody.payment_token = globalState.get("paymentToken"); + saveCardConfirmBody.profile_id = profile_id; + for (const key in reqData) { + saveCardConfirmBody[key] = reqData[key]; } + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments/${paymentIntentID}/confirm`, @@ -1627,11 +1801,11 @@ Cypress.Commands.add( ); expect(response.body.payment_method_data, "payment_method_data").to.not .be.empty; - expect(globalState.get("merchantConnectorId"), "connector_id").to.equal( + expect(merchant_connector_id, "connector_id").to.equal( response.body.merchant_connector_id ); expect(response.body.customer, "customer").to.not.be.empty; - if (req_data.billing !== null) { + if (reqData.billing !== null) { expect(response.body.billing, "billing_address").to.not.be.empty; } expect(response.body.profile_id, "profile_id").to.not.be.null; @@ -1642,10 +1816,9 @@ Cypress.Commands.add( expect(response.body) .to.have.property("next_action") .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } expect(response.body.customer_id).to.equal( globalState.get("customerId") @@ -1662,8 +1835,8 @@ Cypress.Commands.add( .to.have.property("next_action") .to.have.property("redirect_to_url"); } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } expect(response.body.customer_id).to.equal( globalState.get("customerId") @@ -1681,7 +1854,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1689,9 +1862,16 @@ Cypress.Commands.add( Cypress.Commands.add( "captureCallTest", - (requestBody, req_data, res_data, amount_to_capture, globalState) => { + (requestBody, data, amount_to_capture, globalState) => { + const { Configs: configs = {}, Response: resData } = data || {}; + + const config_info = execConfig(validateConfig(configs)); const payment_id = globalState.get("paymentID"); + const profile_id = globalState.get(config_info.profile_id); + requestBody.amount_to_capture = amount_to_capture; + requestBody.profile_id = profile_id; + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments/${payment_id}/capture`, @@ -1707,48 +1887,59 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); if (response.body.capture_method !== undefined) { expect(response.body.payment_id).to.equal(payment_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } ); -Cypress.Commands.add( - "voidCallTest", - (requestBody, req_data, res_data, globalState) => { - const payment_id = globalState.get("paymentID"); - cy.request({ - method: "POST", - url: `${globalState.get("baseUrl")}/payments/${payment_id}/cancel`, - headers: { - "Content-Type": "application/json", - "api-key": globalState.get("apiKey"), - }, - failOnStatusCode: false, - body: requestBody, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); +Cypress.Commands.add("voidCallTest", (requestBody, data, globalState) => { + const { Configs: configs = {}, Response: resData } = data || {}; - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); - } - } else { - defaultErrorHandler(response, res_data); + const config_info = execConfig(validateConfig(configs)); + const payment_id = globalState.get("paymentID"); + const profile_id = globalState.get(config_info.profile_id); + + requestBody.profile_id = profile_id; + + cy.request({ + method: "POST", + url: `${globalState.get("baseUrl")}/payments/${payment_id}/cancel`, + headers: { + "Content-Type": "application/json", + "api-key": globalState.get("apiKey"), + }, + failOnStatusCode: false, + body: requestBody, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } - }); - } -); + } else { + defaultErrorHandler(response, resData); + } + }); +}); Cypress.Commands.add( "retrievePaymentCallTest", - (globalState, autoretries = false, attempt = 1) => { + (globalState, data, autoretries = false, attempt = 1) => { + const { Configs: configs = {} } = data || {}; + + const config_info = execConfig(validateConfig(configs)); + const merchant_connector_id = globalState.get( + config_info.merchant_connector_id + ); const payment_id = globalState.get("paymentID"); + cy.request({ method: "GET", url: `${globalState.get("baseUrl")}/payments/${payment_id}?force_sync=true&expand_attempts=true`, @@ -1759,7 +1950,6 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - globalState.set("paymentID", response.body.payment_id); expect(response.headers["content-type"]).to.include("application/json"); expect(response.body.payment_id).to.equal(payment_id); @@ -1779,7 +1969,7 @@ Cypress.Commands.add( .be.empty; expect(response.body.payment_method, "payment_method").to.not.be.null; expect(response.body.merchant_connector_id, "connector_id").to.equal( - globalState.get("merchantConnectorId") + merchant_connector_id ); } @@ -1793,13 +1983,13 @@ Cypress.Commands.add( for (const key in response.body.attempts) { if ( response.body.attempts[key].attempt_id === - `${payment_id}_${attempt}` && + `${payment_id}_${attempt}` && response.body.status === "succeeded" ) { expect(response.body.attempts[key].status).to.equal("charged"); } else if ( response.body.attempts[key].attempt_id === - `${payment_id}_${attempt}` && + `${payment_id}_${attempt}` && response.body.status === "requires_customer_action" ) { expect(response.body.attempts[key].status).to.equal( @@ -1816,10 +2006,17 @@ Cypress.Commands.add( Cypress.Commands.add( "refundCallTest", - (requestBody, req_data, res_data, refund_amount, globalState) => { + (requestBody, data, refund_amount, globalState) => { + const { Configs: configs = {}, Response: resData } = data || {}; + const payment_id = globalState.get("paymentID"); - requestBody.payment_id = payment_id; + + // we only need this to set the delay. We don't need the return value + execConfig(validateConfig(configs)); + requestBody.amount = refund_amount; + requestBody.payment_id = payment_id; + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/refunds`, @@ -1835,61 +2032,75 @@ Cypress.Commands.add( if (response.status === 200) { globalState.set("refundId", response.body.refund_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } expect(response.body.payment_id).to.equal(payment_id); } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } ); -Cypress.Commands.add( - "syncRefundCallTest", - (req_data, res_data, globalState) => { - const refundId = globalState.get("refundId"); - cy.request({ - method: "GET", - url: `${globalState.get("baseUrl")}/refunds/${refundId}`, - headers: { - "Content-Type": "application/json", - "api-key": globalState.get("apiKey"), - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); +Cypress.Commands.add("syncRefundCallTest", (data, globalState) => { + const { Response: resData } = data || {}; - expect(response.headers["content-type"]).to.include("application/json"); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); - } - }); - } -); + const refundId = globalState.get("refundId"); + + cy.request({ + method: "GET", + url: `${globalState.get("baseUrl")}/refunds/${refundId}`, + headers: { + "Content-Type": "application/json", + "api-key": globalState.get("apiKey"), + }, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + expect(response.headers["content-type"]).to.include("application/json"); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + }); +}); Cypress.Commands.add( "citForMandatesCallTest", ( requestBody, - req_data, - res_data, + data, amount, confirm, capture_method, payment_type, globalState ) => { - for (const key in req_data) { - requestBody[key] = req_data[key]; + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + const config_info = execConfig(validateConfig(configs)); + const profile_id = globalState.get(config_info.profile_id); + const merchant_connector_id = globalState.get( + config_info.merchant_connector_id + ); + + for (const key in reqData) { + requestBody[key] = reqData[key]; } - requestBody.payment_type = payment_type; - requestBody.confirm = confirm; requestBody.amount = amount; requestBody.capture_method = capture_method; + requestBody.confirm = confirm; requestBody.customer_id = globalState.get("customerId"); + requestBody.payment_type = payment_type; + requestBody.profile_id = profile_id; + globalState.set("paymentAmount", requestBody.amount); + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments`, @@ -1910,7 +2121,7 @@ Cypress.Commands.add( expect(response.body.connector, "connector").to.equal( globalState.get("connectorId") ); - expect(globalState.get("merchantConnectorId"), "connector_id").to.equal( + expect(merchant_connector_id, "connector_id").to.equal( response.body.merchant_connector_id ); expect(response.body.customer, "customer").to.not.be.empty; @@ -1940,12 +2151,12 @@ Cypress.Commands.add( response.body.next_action.redirect_to_url ); cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { throw new Error( @@ -1963,12 +2174,12 @@ Cypress.Commands.add( response.body.next_action.redirect_to_url ); cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { throw new Error( @@ -1981,7 +2192,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -1989,23 +2200,30 @@ Cypress.Commands.add( Cypress.Commands.add( "mitForMandatesCallTest", - ( - requestBody, - req_data, - res_data, - amount, - confirm, - capture_method, - globalState - ) => { - for (const key in req_data) { - requestBody[key] = req_data[key]; + (requestBody, data, amount, confirm, capture_method, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + const config_info = execConfig(validateConfig(configs)); + const profile_id = globalState.get(config_info.profile_id); + + for (const key in reqData) { + requestBody[key] = reqData[key]; } + + const merchant_connector_id = globalState.get( + config_info.merchant_connector_id + ); + requestBody.amount = amount; requestBody.confirm = confirm; requestBody.capture_method = capture_method; - requestBody.mandate_id = globalState.get("mandateId"); requestBody.customer_id = globalState.get("customerId"); + requestBody.mandate_id = globalState.get("mandateId"); + requestBody.profile_id = profile_id; + globalState.set("paymentAmount", requestBody.amount); cy.request({ method: "POST", @@ -2026,7 +2244,7 @@ Cypress.Commands.add( expect(response.body.connector, "connector").to.equal( globalState.get("connectorId") ); - expect(globalState.get("merchantConnectorId"), "connector_id").to.equal( + expect(merchant_connector_id, "connector_id").to.equal( response.body.merchant_connector_id ); expect(response.body.customer, "customer").to.not.be.empty; @@ -2040,12 +2258,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2059,12 +2277,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2087,7 +2305,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2095,23 +2313,27 @@ Cypress.Commands.add( Cypress.Commands.add( "mitUsingPMId", - ( - requestBody, - req_data, - res_data, - amount, - confirm, - capture_method, - globalState - ) => { - for (const key in req_data) { - requestBody[key] = req_data[key]; + (requestBody, data, amount, confirm, capture_method, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + + for (const key in reqData) { + requestBody[key] = reqData[key]; } + + const configInfo = execConfig(validateConfig(configs)); + const profileId = globalState.get(configInfo.profile_id); + requestBody.amount = amount; - requestBody.confirm = confirm; requestBody.capture_method = capture_method; - requestBody.recurring_details.data = globalState.get("paymentMethodId"); + requestBody.confirm = confirm; requestBody.customer_id = globalState.get("customerId"); + requestBody.profile_id = profileId; + requestBody.recurring_details.data = globalState.get("paymentMethodId"); + cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments`, @@ -2133,12 +2355,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2152,12 +2374,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2170,7 +2392,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2178,25 +2400,23 @@ Cypress.Commands.add( Cypress.Commands.add( "mitUsingNTID", - ( - requestBody, - req_data, - res_data, - amount, - confirm, - capture_method, - globalState - ) => { - for (const key in req_data) { - requestBody[key] = req_data[key]; + (requestBody, data, amount, confirm, capture_method, globalState) => { + const { + Configs: configs = {}, + Request: reqData, + Response: resData, + } = data || {}; + const configInfo = execConfig(validateConfig(configs)); + const profileId = globalState.get(configInfo.profile_id); + + for (const key in reqData) { + requestBody[key] = reqData[key]; } + requestBody.amount = amount; requestBody.confirm = confirm; requestBody.capture_method = capture_method; - - if (globalState.get("connectorId") !== "cybersource") { - return; - } + requestBody.profile_id = profileId; const apiKey = globalState.get("apiKey"); const baseUrl = globalState.get("baseUrl"); @@ -2226,12 +2446,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2245,12 +2465,12 @@ Cypress.Commands.add( .to.have.property("redirect_to_url"); const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else if (response.body.authentication_type === "no_three_ds") { - for (const key in res_data.body) { - expect(res_data.body[key], [key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); } } else { throw new Error( @@ -2263,7 +2483,7 @@ Cypress.Commands.add( ); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2317,9 +2537,9 @@ Cypress.Commands.add("revokeMandateCallTest", (globalState) => { Cypress.Commands.add( "handleRedirection", (globalState, expected_redirection) => { - let connectorId = globalState.get("connectorId"); - let expected_url = new URL(expected_redirection); - let redirection_url = new URL(globalState.get("nextActionUrl")); + const connectorId = globalState.get("connectorId"); + const expected_url = new URL(expected_redirection); + const redirection_url = new URL(globalState.get("nextActionUrl")); handleRedirection( "three_ds", { redirection_url, expected_url }, @@ -2332,9 +2552,10 @@ Cypress.Commands.add( Cypress.Commands.add( "handleBankRedirectRedirection", (globalState, payment_method_type, expected_redirection) => { - let connectorId = globalState.get("connectorId"); - let expected_url = new URL(expected_redirection); - let redirection_url = new URL(globalState.get("nextActionUrl")); + const connectorId = globalState.get("connectorId"); + const expected_url = new URL(expected_redirection); + const redirection_url = new URL(globalState.get("nextActionUrl")); + // explicitly restricting `sofort` payment method by adyen from running as it stops other tests from running // trying to handle that specific case results in stripe 3ds tests to fail if (!(connectorId == "adyen" && payment_method_type == "sofort")) { @@ -2351,10 +2572,11 @@ Cypress.Commands.add( Cypress.Commands.add( "handleBankTransferRedirection", (globalState, payment_method_type, expected_redirection) => { - let connectorId = globalState.get("connectorId"); - let expected_url = new URL(expected_redirection); - let redirection_url = new URL(globalState.get("nextActionUrl")); - let next_action_type = globalState.get("nextActionType"); + const connectorId = globalState.get("connectorId"); + const expected_url = new URL(expected_redirection); + const redirection_url = new URL(globalState.get("nextActionUrl")); + const next_action_type = globalState.get("nextActionType"); + cy.log(payment_method_type); handleRedirection( "bank_transfer", @@ -2371,9 +2593,10 @@ Cypress.Commands.add( Cypress.Commands.add( "handleUpiRedirection", (globalState, payment_method_type, expected_redirection) => { - let connectorId = globalState.get("connectorId"); - let expected_url = new URL(expected_redirection); - let redirection_url = new URL(globalState.get("nextActionUrl")); + const connectorId = globalState.get("connectorId"); + const expected_url = new URL(expected_redirection); + const redirection_url = new URL(globalState.get("nextActionUrl")); + handleRedirection( "upi", { redirection_url, expected_url }, @@ -2480,16 +2703,11 @@ Cypress.Commands.add("listRefundCallTest", (requestBody, globalState) => { Cypress.Commands.add( "createConfirmPayoutTest", - ( - createConfirmPayoutBody, - req_data, - res_data, - confirm, - auto_fulfill, - globalState - ) => { - for (const key in req_data) { - createConfirmPayoutBody[key] = req_data[key]; + (createConfirmPayoutBody, data, confirm, auto_fulfill, globalState) => { + const { Request: reqData, Response: resData } = data || {}; + + for (const key in reqData) { + createConfirmPayoutBody[key] = reqData[key]; } createConfirmPayoutBody.auto_fulfill = auto_fulfill; createConfirmPayoutBody.confirm = confirm; @@ -2511,11 +2729,11 @@ Cypress.Commands.add( if (response.status === 200) { globalState.set("payoutAmount", createConfirmPayoutBody.amount); globalState.set("payoutID", response.body.payout_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2523,16 +2741,11 @@ Cypress.Commands.add( Cypress.Commands.add( "createConfirmWithTokenPayoutTest", - ( - createConfirmPayoutBody, - req_data, - res_data, - confirm, - auto_fulfill, - globalState - ) => { - for (const key in req_data) { - createConfirmPayoutBody[key] = req_data[key]; + (createConfirmPayoutBody, data, confirm, auto_fulfill, globalState) => { + const { Request: reqData, Response: resData } = data || {}; + + for (const key in reqData) { + createConfirmPayoutBody[key] = reqData[key]; } createConfirmPayoutBody.customer_id = globalState.get("customerId"); createConfirmPayoutBody.payout_token = globalState.get("paymentToken"); @@ -2555,11 +2768,11 @@ Cypress.Commands.add( if (response.status === 200) { globalState.set("payoutAmount", createConfirmPayoutBody.amount); globalState.set("payoutID", response.body.payout_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2567,7 +2780,9 @@ Cypress.Commands.add( Cypress.Commands.add( "fulfillPayoutCallTest", - (payoutFulfillBody, req_data, res_data, globalState) => { + (payoutFulfillBody, data, globalState) => { + const { Response: resData } = data || {}; + payoutFulfillBody.payout_id = globalState.get("payoutID"); cy.request({ @@ -2584,11 +2799,11 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); if (response.status === 200) { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2596,7 +2811,9 @@ Cypress.Commands.add( Cypress.Commands.add( "updatePayoutCallTest", - (payoutConfirmBody, req_data, res_data, auto_fulfill, globalState) => { + (payoutConfirmBody, data, auto_fulfill, globalState) => { + const { Response: resData } = data || {}; + payoutConfirmBody.confirm = true; payoutConfirmBody.auto_fulfill = auto_fulfill; @@ -2614,11 +2831,11 @@ Cypress.Commands.add( expect(response.headers["content-type"]).to.include("application/json"); if (response.status === 200) { - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } @@ -2770,14 +2987,16 @@ Cypress.Commands.add("ListMcaByMid", (globalState) => { Cypress.Commands.add( "addRoutingConfig", - (routingBody, req_data, res_data, type, data, globalState) => { - for (const key in req_data) { - routingBody[key] = req_data[key]; + (routingBody, data, type, routing_data, globalState) => { + const { Request: reqData, Response: resData } = data || {}; + + for (const key in reqData) { + routingBody[key] = reqData[key]; } // set profile id from env routingBody.profile_id = globalState.get("profileId"); routingBody.algorithm.type = type; - routingBody.algorithm.data = data; + routingBody.algorithm.data = routing_data; cy.request({ method: "POST", @@ -2796,73 +3015,71 @@ Cypress.Commands.add( if (response.status === 200) { expect(response.body).to.have.property("id"); globalState.set("routingConfigId", response.body.id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } } else { - defaultErrorHandler(response, res_data); + defaultErrorHandler(response, resData); } }); } ); -Cypress.Commands.add( - "activateRoutingConfig", - (req_data, res_data, globalState) => { - let routing_config_id = globalState.get("routingConfigId"); - cy.request({ - method: "POST", - url: `${globalState.get("baseUrl")}/routing/${routing_config_id}/activate`, - headers: { - Authorization: `Bearer ${globalState.get("userInfoToken")}`, - "Content-Type": "application/json", - Cookie: `${globalState.get("cookie")}`, - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); +Cypress.Commands.add("activateRoutingConfig", (data, globalState) => { + const { Response: resData } = data || {}; - if (response.status === 200) { - expect(response.body.id).to.equal(routing_config_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); - } - } else { - defaultErrorHandler(response, res_data); + const routing_config_id = globalState.get("routingConfigId"); + cy.request({ + method: "POST", + url: `${globalState.get("baseUrl")}/routing/${routing_config_id}/activate`, + headers: { + Authorization: `Bearer ${globalState.get("userInfoToken")}`, + "Content-Type": "application/json", + Cookie: `${globalState.get("cookie")}`, + }, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + expect(response.headers["content-type"]).to.include("application/json"); + + if (response.status === 200) { + expect(response.body.id).to.equal(routing_config_id); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } - }); - } -); + } else { + defaultErrorHandler(response, resData); + } + }); +}); -Cypress.Commands.add( - "retrieveRoutingConfig", - (req_data, res_data, globalState) => { - let routing_config_id = globalState.get("routingConfigId"); - cy.request({ - method: "GET", - url: `${globalState.get("baseUrl")}/routing/${routing_config_id}`, - headers: { - Authorization: `Bearer ${globalState.get("userInfoToken")}`, - "Content-Type": "application/json", - Cookie: `${globalState.get("cookie")}`, - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); +Cypress.Commands.add("retrieveRoutingConfig", (data, globalState) => { + const { Response: resData } = data || {}; - if (response.status === 200) { - expect(response.body.id).to.equal(routing_config_id); - for (const key in res_data.body) { - expect(res_data.body[key]).to.equal(response.body[key]); - } - } else { - defaultErrorHandler(response, res_data); + const routing_config_id = globalState.get("routingConfigId"); + cy.request({ + method: "GET", + url: `${globalState.get("baseUrl")}/routing/${routing_config_id}`, + headers: { + Authorization: `Bearer ${globalState.get("userInfoToken")}`, + "Content-Type": "application/json", + Cookie: `${globalState.get("cookie")}`, + }, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + expect(response.headers["content-type"]).to.include("application/json"); + + if (response.status === 200) { + expect(response.body.id).to.equal(routing_config_id); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); } - }); - } -); + } else { + defaultErrorHandler(response, resData); + } + }); +}); Cypress.Commands.add( "updateGsmConfig", @@ -2892,55 +3109,118 @@ Cypress.Commands.add( } ); -Cypress.Commands.add( - "updateConfig", - (configType, configData, globalState, value) => { - const base_url = globalState.get("baseUrl"); - const merchant_id = globalState.get("merchantId"); - const api_key = globalState.get("adminApiKey"); +Cypress.Commands.add("updateConfig", (configType, globalState, value) => { + const base_url = globalState.get("baseUrl"); + const merchant_id = globalState.get("merchantId"); + const api_key = globalState.get("adminApiKey"); + + let key; + let url; + let body; + + switch (configType) { + case "autoRetry": + key = `should_call_gsm_${merchant_id}`; + url = `${base_url}/configs/${key}`; + body = { key: key, value: value }; + break; + case "maxRetries": + key = `max_auto_retries_enabled_${merchant_id}`; + url = `${base_url}/configs/${key}`; + body = { key: key, value: value }; + break; + case "stepUp": + key = `step_up_enabled_${merchant_id}`; + url = `${base_url}/configs/${key}`; + body = { key: key, value: value }; + break; + default: + throw new Error( + `Invalid config type passed into the configs: "${api_key}: ${value}"` + ); + } - let key; - let url; - let body; - - switch (configType) { - case "autoRetry": - key = `should_call_gsm_${merchant_id}`; - url = `${base_url}/configs/${key}`; - body = { key: key, value: value }; - break; - case "maxRetries": - key = `max_auto_retries_enabled_${merchant_id}`; - url = `${base_url}/configs/${key}`; - body = { key: key, value: value }; - break; - case "stepUp": - key = `step_up_enabled_${merchant_id}`; - url = `${base_url}/configs/${key}`; - body = { key: key, value: value }; - break; - default: - throw new Error( - `Invalid config type passed into the configs: "${api_key}: ${value}"` - ); + cy.request({ + method: "POST", + url: url, + headers: { + "Content-Type": "application/json", + "api-key": api_key, + }, + body: body, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + if (response.status === 200) { + expect(response.body).to.have.property("key").to.equal(key); + expect(response.body).to.have.property("value").to.equal(value); } + }); +}); - cy.request({ - method: "POST", - url: url, - headers: { - "Content-Type": "application/json", - "api-key": api_key, - }, - body: body, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); +Cypress.Commands.add("incrementalAuth", (globalState, data) => { + const { Request: reqData, Response: resData } = data || {}; - if (response.status === 200) { - expect(response.body).to.have.property("key").to.equal(key); - expect(response.body).to.have.property("value").to.equal(value); + const baseUrl = globalState.get("baseUrl"); + const paymentId = globalState.get("paymentID"); + const apiKey = globalState.get("apiKey"); + const url = `${baseUrl}/payments/${paymentId}/incremental_authorization`; + + cy.request({ + method: "POST", + url: url, + headers: { + "api-key": apiKey, + "Content-Type": "application/json", + }, + body: reqData, + failOnStatusCode: false, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + if (response.status === 200) { + expect(response.body.amount_capturable, "amount_capturable").to.equal( + resData.body.amount_capturable + ); + expect(response.body.authorization_count, "authorization_count").to.be.a( + "number" + ).and.not.be.null; + expect( + response.body.incremental_authorization_allowed, + "incremental_authorization_allowed" + ).to.be.true; + expect( + response.body.incremental_authorizations, + "incremental_authorizations" + ).to.be.an("array").and.not.be.empty; + expect(response.body.payment_id, "payment_id").to.equal(paymentId); + expect(response.body.status, "status").to.equal(resData.body.status); + + for (const key in response.body.incremental_authorizations) { + expect(response.body.incremental_authorizations[key], "amount") + .to.have.property("amount") + .to.be.a("number") + .to.equal(resData.body.amount).and.not.be.null; + expect( + response.body.incremental_authorizations[key], + "error_code" + ).to.have.property("error_code").to.be.null; + expect( + response.body.incremental_authorizations[key], + "error_message" + ).to.have.property("error_message").to.be.null; + expect( + response.body.incremental_authorizations[key], + "previously_authorized_amount" + ) + .to.have.property("previously_authorized_amount") + .to.be.a("number") + .to.equal(response.body.amount).and.not.be.null; + expect(response.body.incremental_authorizations[key], "status") + .to.have.property("status") + .to.equal("success"); } - }); - } -); + } + }); +}); diff --git a/cypress-tests/cypress/support/redirectionHandler.js b/cypress-tests/cypress/support/redirectionHandler.js index ee8e21979034..7c1675690eea 100644 --- a/cypress-tests/cypress/support/redirectionHandler.js +++ b/cypress-tests/cypress/support/redirectionHandler.js @@ -1,9 +1,10 @@ +/* eslint-disable cypress/unsafe-to-chain-command */ +/* eslint-disable cypress/no-unnecessary-waiting */ import jsQR from "jsqr"; // Define constants for wait times const TIMEOUT = 20000; // 20 seconds const WAIT_TIME = 10000; // 10 seconds -const WAIT_TIME_IATAPAY = 20000; // 20 seconds export function handleRedirection( redirection_type, @@ -156,7 +157,7 @@ function bankRedirectRedirection( cy.get("button.cookie-modal-deny-all.button-tertiary") .should("be.visible") .should("contain", "Reject All") - .click({ force: true, multiple: true }); + .click({ multiple: true }); cy.get("div#TopBanks.top-banks-multistep") .should("contain", "Demo Bank") .as("btn") @@ -280,7 +281,7 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { if (connectorId === "adyen") { cy.get("iframe") .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get('input[type="password"]').click(); cy.get('input[type="password"]').type("password"); cy.get("#buttonSubmit").click(); @@ -292,17 +293,17 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { ) { cy.get("iframe", { timeout: TIMEOUT }) .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get('input[type="text"]').click().type("1234"); cy.get('input[value="SUBMIT"]').click(); }); } else if (connectorId === "checkout") { cy.get("iframe", { timeout: TIMEOUT }) .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get('form[id="form"]', { timeout: WAIT_TIME }) .should("exist") - .then((form) => { + .then(() => { cy.get('input[id="password"]').click(); cy.get('input[id="password"]').type("Checkout1!"); cy.get("#txtButton").click(); @@ -311,13 +312,13 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { } else if (connectorId === "nmi" || connectorId === "noon") { cy.get("iframe", { timeout: TIMEOUT }) .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get("iframe", { timeout: TIMEOUT }) .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get('form[name="cardholderInput"]', { timeout: TIMEOUT }) .should("exist") - .then((form) => { + .then(() => { cy.get('input[name="challengeDataEntry"]').click().type("1234"); cy.get('input[value="SUBMIT"]').click(); }); @@ -326,23 +327,23 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { } else if (connectorId === "novalnet") { cy.get("form", { timeout: WAIT_TIME }) .should("exist") - .then((form) => { + .then(() => { cy.get('input[id="submit"]').click(); }); } else if (connectorId === "stripe") { cy.get("iframe", { timeout: TIMEOUT }) .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get("iframe") .its("0.contentDocument.body") - .within((body) => { + .within(() => { cy.get("#test-source-authorize-3ds").click(); }); }); } else if (connectorId === "trustpay") { cy.get('form[name="challengeForm"]', { timeout: WAIT_TIME }) .should("exist") - .then((form) => { + .then(() => { cy.get("#outcomeSelect").select("Approve").should("have.value", "Y"); cy.get('button[type="submit"]').click(); }); @@ -358,16 +359,16 @@ function threeDsRedirection(redirection_url, expected_url, connectorId) { }); }); } else if (connectorId === "fiuu") { - cy.get('form[id="cc_form"]', { timeout: WAIT_TIME_IATAPAY }) + cy.get('form[id="cc_form"]', { timeout: TIMEOUT }) .should("exist") - .then((form) => { + .then(() => { cy.get('button.pay-btn[name="pay"]').click(); cy.get("div.otp") .invoke("text") .then((otpText) => { const otp = otpText.match(/\d+/)[0]; // Extract the numeric OTP cy.get("input#otp-input").should("not.be.disabled").type(otp); - cy.get('button.pay-btn').click(); + cy.get("button.pay-btn").click(); }); }); } else { @@ -391,7 +392,7 @@ function upiRedirection( switch (payment_method_type) { case "upi_collect": cy.visit(redirection_url.href); - cy.wait(WAIT_TIME_IATAPAY).then(() => { + cy.wait(TIMEOUT).then(() => { verifyUrl = true; }); break; diff --git a/cypress-tests/cypress/utils/featureFlags.js b/cypress-tests/cypress/utils/featureFlags.js new file mode 100644 index 000000000000..7140aee3af7e --- /dev/null +++ b/cypress-tests/cypress/utils/featureFlags.js @@ -0,0 +1,156 @@ +/* eslint-disable no-console */ +const config_fields = ["CONNECTOR_CREDENTIAL", "DELAY", "TRIGGER_SKIP"]; + +const DEFAULT_CONNECTOR = "connector_1"; +const DEFAULT_CREDENTIALS = { + profile_id: "profileId", + merchant_connector_id: "merchantConnectorId", +}; +const CONNECTOR_2_CREDENTIALS = { + profile_id: "profile1Id", + merchant_connector_id: "merchantConnector1Id", +}; + +// Helper function for type and range validation +function validateType(value, type) { + if (typeof value !== type) { + console.error( + `Expected value to be of type ${type}, but got ${typeof value}.` + ); + return false; + } + return true; +} + +// Helper function to validate specific config keys based on schema rules +function validateConfigValue(key, value) { + // At present, there are only 2 api keys for connectors. Will be scaled based on the need + const SUPPORTED_CONNECTOR_CREDENTIAL = ["connector_1", "connector_2"]; + + if (config_fields.includes(key)) { + switch (key) { + case "DELAY": + if (typeof value !== "object" || value === null) { + console.error("DELAY must be an object."); + return false; + } + if (!validateType(value.STATUS, "boolean")) return false; + if ( + !value.STATUS || + typeof value.TIMEOUT !== "number" || + value.TIMEOUT < 0 || + value.TIMEOUT > 30000 + ) { + console.error( + "DELAY.TIMEOUT must be an integer between 0 and 30000 and DELAY.STATUS must be enabled." + ); + return false; + } + break; + + case "CONNECTOR_CREDENTIAL": + if (typeof value !== "object" || value === null) { + console.error("CONNECTOR_CREDENTIAL must be an object."); + return false; + } + // Validate structure + if ( + !value.value || + !SUPPORTED_CONNECTOR_CREDENTIAL.includes(value.value) + ) { + console.error( + `Config ${key}.value must be one of ${SUPPORTED_CONNECTOR_CREDENTIAL.join(", ")}.` + ); + return false; + } + break; + + case "TRIGGER_SKIP": + case "DELAY.STATUS": + if (!validateType(value, "boolean")) return false; + break; + + default: + console.error(`Config key ${key} is invalid.`); + return false; + } + } else { + console.error(`Config key ${key} is invalid.`); + } + return true; +} + +// Function to validate the config object +export function validateConfig(configObject) { + // Configs object is an optional field in Connector Configs + // If passed, it must be a valid Object + if (typeof configObject === "undefined") { + return null; + } else if (typeof configObject !== "object" || configObject === null) { + console.error(`Provided config is invalid:\n${configObject}`); + return null; + } + + for (const key in configObject) { + if (Object.prototype.hasOwnProperty.call(configObject, key)) { + const value = configObject[key]; + if (!validateConfigValue(key, value)) { + return null; // Return null if any validation fails + } + } + } + + return configObject; +} + +export function execConfig(configs) { + // Handle delay if present + if (configs?.DELAY?.STATUS) { + cy.wait(configs.DELAY.TIMEOUT); + } + if ( + typeof configs?.CONNECTOR_CREDENTIAL === "undefined" || + configs?.CONNECTOR_CREDENTIAL.value === "null" + ) { + return DEFAULT_CREDENTIALS; + } + + // Get connector configuration + const connectorType = determineConnectorConfig(configs.CONNECTOR_CREDENTIAL); + + // Return credentials based on connector type + return connectorType === "connector_2" + ? CONNECTOR_2_CREDENTIALS + : DEFAULT_CREDENTIALS; +} + +function determineConnectorConfig(connectorConfig) { + // Return default if config is undefined or null + if (!connectorConfig || connectorConfig.value === "null") { + return DEFAULT_CONNECTOR; + } + + const { specName = null, value } = connectorConfig; + + // If value is not provided, return default + if (!value) { + return DEFAULT_CONNECTOR; + } + + // If no specName or not an array, return value directly + if (!specName || !Array.isArray(specName) || specName.length === 0) { + return value; + } + + // Check if current spec matches any in specName + const currentSpec = Cypress.spec.name.toLowerCase(); + try { + const matchesSpec = specName.some( + (name) => name && currentSpec.includes(name.toLowerCase()) + ); + return matchesSpec ? value : DEFAULT_CONNECTOR; + } catch (error) { + console.error("Error matching spec names:", error); + return DEFAULT_CONNECTOR; + } +} diff --git a/cypress-tests/eslint.config.js b/cypress-tests/eslint.config.js new file mode 100644 index 000000000000..5e77513c97b8 --- /dev/null +++ b/cypress-tests/eslint.config.js @@ -0,0 +1,36 @@ +import pluginJs from "@eslint/js"; +import eslintConfigPrettier from "eslint-config-prettier"; +import pluginCypress from "eslint-plugin-cypress/flat"; +import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; +import globals from "globals"; + +/** @type {import('eslint').Linter.Config[]} */ +export default [ + pluginJs.configs.recommended, + pluginCypress.configs.recommended, + eslintPluginPrettierRecommended, + eslintConfigPrettier, + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + }, + }, + rules: { + "no-unused-vars": "error", + "no-undef": "error", + "no-console": "warn", + "prefer-const": "warn", + + "cypress/assertion-before-screenshot": "warn", + "cypress/no-assigning-return-values": "warn", + "cypress/no-force": "warn", + "cypress/no-unnecessary-waiting": "warn", + "cypress/no-async-tests": "error", + "cypress/unsafe-to-chain-command": "warn", + + "prettier/prettier": "error", + }, + }, +]; diff --git a/cypress-tests/package-lock.json b/cypress-tests/package-lock.json index 04390f76f1d0..a2c2c4b8fb24 100644 --- a/cypress-tests/package-lock.json +++ b/cypress-tests/package-lock.json @@ -9,10 +9,16 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { + "@eslint/js": "^9.16.0", "cypress": "^13.16.0", "cypress-mochawesome-reporter": "^3.8.2", + "eslint": "^9.16.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^4.1.0", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.13.0", "jsqr": "^1.4.0", - "prettier": "^3.3.2" + "prettier": "^3.4.1" } }, "node_modules/@colors/colors": { @@ -77,15 +83,245 @@ "ms": "^2.1.1" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { - "version": "22.1.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.1.0.tgz", - "integrity": "sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "dev": true, "license": "MIT", "optional": true, "dependencies": { - "undici-types": "~6.13.0" + "undici-types": "~6.20.0" } }, "node_modules/@types/sinonjs__fake-timers": { @@ -96,9 +332,9 @@ "license": "MIT" }, "node_modules/@types/sizzle": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.8.tgz", - "integrity": "sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==", + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", + "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", "dev": true, "license": "MIT" }, @@ -113,6 +349,29 @@ "@types/node": "*" } }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", @@ -127,6 +386,23 @@ "node": ">=8" } }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -220,8 +496,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "license": "Python-2.0", - "peer": true + "license": "Python-2.0" }, "node_modules/asn1": { "version": "0.2.6", @@ -254,9 +529,9 @@ } }, "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, "license": "MIT" }, @@ -361,14 +636,14 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, "node_modules/braces": { @@ -458,6 +733,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -545,6 +830,20 @@ "fsevents": "~2.3.2" } }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", @@ -853,20 +1152,20 @@ } }, "node_modules/dayjs": { - "version": "1.11.12", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", - "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==", + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", "dev": true, "license": "MIT" }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -891,6 +1190,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -995,9 +1301,9 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -1012,13 +1318,227 @@ "license": "MIT" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", + "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.16.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.5", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-cypress": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-4.1.0.tgz", + "integrity": "sha512-JhqkMY02mw74USwK9OFhectx3YSj6Co1NgWBxlGdKvlqiAp9vdEuQqt33DKGQFvvGS/NWtduuhWXWNnU29xDSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globals": "^15.11.0" + }, + "peerDependencies": { + "eslint": ">=9" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" } }, "node_modules/eventemitter2": { @@ -1035,7 +1555,7 @@ "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.6", + "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", "human-signals": "^1.1.1", "is-stream": "^2.0.0", @@ -1103,6 +1623,34 @@ ], "license": "MIT" }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -1129,6 +1677,29 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -1149,7 +1720,6 @@ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -1172,6 +1742,27 @@ "flat": "cli.js" } }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1342,17 +1933,41 @@ } }, "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", "peer": true, "dependencies": { - "is-glob": "^4.0.1" + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 6" + "node": ">=10" } }, "node_modules/global-dirs": { @@ -1371,6 +1986,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globals": { + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", + "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -1510,6 +2138,43 @@ ], "license": "BSD-3-Clause" }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -1569,7 +2234,6 @@ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -1590,7 +2254,6 @@ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -1707,7 +2370,6 @@ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "argparse": "^2.0.1" }, @@ -1722,6 +2384,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", @@ -1729,6 +2398,20 @@ "dev": true, "license": "(AFL-2.1 OR BSD-3-Clause)" }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1772,6 +2455,16 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -1782,6 +2475,20 @@ "node": "> 0.8" } }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/listr2": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", @@ -1816,7 +2523,6 @@ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -1862,6 +2568,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -1992,17 +2705,16 @@ } }, "node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", - "peer": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" } }, "node_modules/minimist": { @@ -2016,9 +2728,9 @@ } }, "node_modules/mocha": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.0.tgz", - "integrity": "sha512-v8/rBWr2VO5YkspYINnvu81inSz2y3ODJrhO175/Exzor1RcEZZkizgE2A+w/CAXXoESS8Kys5E62dOHGHzULA==", + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", "dev": true, "license": "MIT", "peer": true, @@ -2052,27 +2764,30 @@ "node": ">= 14.0.0" } }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "license": "MIT", "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, - "license": "MIT", - "peer": true + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } }, "node_modules/mochawesome": { "version": "7.1.3", @@ -2114,17 +2829,6 @@ "node": ">=10.0.0" } }, - "node_modules/mochawesome-merge/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/mochawesome-merge/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2231,19 +2935,6 @@ "node": ">=8" } }, - "node_modules/mochawesome-merge/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/mochawesome-merge/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -2426,9 +3117,16 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, @@ -2515,6 +3213,24 @@ "opener": "bin/opener-bin.js" } }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/ospath": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", @@ -2528,7 +3244,6 @@ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -2545,7 +3260,6 @@ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -2582,6 +3296,19 @@ "node": ">=6" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2650,10 +3377,20 @@ "node": ">=0.10.0" } }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.1.tgz", + "integrity": "sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg==", "dev": true, "license": "MIT", "bin": { @@ -2666,6 +3403,19 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -2709,9 +3459,9 @@ "license": "MIT" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, "license": "MIT", "dependencies": { @@ -2719,6 +3469,16 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -2794,6 +3554,16 @@ "dev": true, "license": "ISC" }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -3036,7 +3806,6 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" }, @@ -3060,6 +3829,23 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tcomb": { "version": "3.2.29", "resolved": "https://registry.npmjs.org/tcomb/-/tcomb-3.2.29.tgz", @@ -3095,22 +3881,22 @@ "license": "MIT" }, "node_modules/tldts": { - "version": "6.1.62", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.62.tgz", - "integrity": "sha512-TF+wo3MgTLbf37keEwQD0IxvOZO8UZxnpPJDg5iFGAASGxYzbX/Q0y944ATEjrfxG/pF1TWRHCPbFp49Mz1Y1w==", + "version": "6.1.64", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.64.tgz", + "integrity": "sha512-ph4AE5BXWIOsSy9stpoeo7bYe/Cy7VfpciIH4RhVZUPItCJmhqWCN0EVzxd8BOHiyNb42vuJc6NWTjJkg91Tuw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.62" + "tldts-core": "^6.1.64" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.62", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.62.tgz", - "integrity": "sha512-ohONqbfobpuaylhqFbtCzc0dFFeNz85FVKSesgT8DS9OV3a25Yj730pTj7/dDtCqmgoCgEj6gDiU9XxgHKQlBw==", + "version": "6.1.64", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz", + "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==", "dev": true, "license": "MIT" }, @@ -3162,9 +3948,9 @@ } }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, "license": "0BSD" }, @@ -3188,6 +3974,19 @@ "dev": true, "license": "Unlicense" }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", @@ -3202,9 +4001,9 @@ } }, "node_modules/undici-types": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.13.0.tgz", - "integrity": "sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "dev": true, "license": "MIT", "optional": true @@ -3229,6 +4028,16 @@ "node": ">=8" } }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, "node_modules/uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -3287,6 +4096,16 @@ "dev": true, "license": "ISC" }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/workerpool": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", @@ -3395,7 +4214,6 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, diff --git a/cypress-tests/package.json b/cypress-tests/package.json index 204e3393d0a1..ff168f61effb 100644 --- a/cypress-tests/package.json +++ b/cypress-tests/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "", "main": "index.js", + "type": "module", "scripts": { "cypress": "npx cypress open", "cypress-e2e": "npx cypress run --e2e", @@ -10,14 +11,23 @@ "cypress:payments": "cypress run --headless --spec 'cypress/e2e/PaymentTest/**/*'", "cypress:payouts": "cypress run --headless --spec 'cypress/e2e/PayoutTest/**/*'", "cypress:payment-method-list": "cypress run --headless --spec 'cypress/e2e/PaymentMethodListTest/**/*'", - "cypress:routing": "cypress run --headless --spec 'cypress/e2e/RoutingTest/**/*'" + "cypress:routing": "cypress run --headless --spec 'cypress/e2e/RoutingTest/**/*'", + "format": "prettier --config .prettierrc . --write", + "format:check": "prettier --config .prettierrc . --check", + "lint": "eslint ." }, - "author": "", + "author": "Hyperswitch", "license": "ISC", "devDependencies": { + "@eslint/js": "^9.16.0", "cypress": "^13.16.0", "cypress-mochawesome-reporter": "^3.8.2", + "eslint": "^9.16.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-cypress": "^4.1.0", + "eslint-plugin-prettier": "^5.2.1", + "globals": "^15.13.0", "jsqr": "^1.4.0", - "prettier": "^3.3.2" + "prettier": "^3.4.1" } } diff --git a/migrations/2024-11-24-104438_add_error_category_col_to_gsm/down.sql b/migrations/2024-11-24-104438_add_error_category_col_to_gsm/down.sql new file mode 100644 index 000000000000..609afbdfd753 --- /dev/null +++ b/migrations/2024-11-24-104438_add_error_category_col_to_gsm/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE gateway_status_map DROP COLUMN error_category; diff --git a/migrations/2024-11-24-104438_add_error_category_col_to_gsm/up.sql b/migrations/2024-11-24-104438_add_error_category_col_to_gsm/up.sql new file mode 100644 index 000000000000..298f6d263aa2 --- /dev/null +++ b/migrations/2024-11-24-104438_add_error_category_col_to_gsm/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE gateway_status_map ADD COLUMN error_category VARCHAR(64);