diff --git a/.github/data/cards_info.csv b/.github/data/cards_info.csv index 4e7a19e4b23..f358214cc90 100644 --- a/.github/data/cards_info.csv +++ b/.github/data/cards_info.csv @@ -11,3 +11,4 @@ card_iin,card_issuer,card_network,card_type,card_subtype,card_issuing_country,ba 491761,BANKPOLSKAKASAOPIEKIS.A.(BANKPEKAOSA),Visa,CREDIT,BUSINESS,POLAND,,,,2015-09-07 12:58:50,, 510510,BANKOFHAWAII,Mastercard,CREDIT,,UNITEDSTATES,,,,2015-07-30 05:18:28,, 520474,MASTERCARD INTERNATIONAL,Visa,DEBIT,,UNITEDSTATES,,,840,2016-05-12 18:51:16,2022-12-12 15:17:33,Visa +378282,AmericanExpress,AmericanExpress,CREDIT,SMALLCORPORATE,INDIA,107,JP_AMEX,,2015-07-25 06:22:06,2021-02-23 07:37:55, \ No newline at end of file diff --git a/.github/workflows/CI-pr.yml b/.github/workflows/CI-pr.yml index d01c26d5112..b337a179959 100644 --- a/.github/workflows/CI-pr.yml +++ b/.github/workflows/CI-pr.yml @@ -90,7 +90,7 @@ jobs: env: # Use `sccache` for caching compilation artifacts - RUSTC_WRAPPER: sccache + # RUSTC_WRAPPER: sccache RUSTFLAGS: "-D warnings" strategy: @@ -126,11 +126,16 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Install sccache - uses: taiki-e/install-action@v2.33.28 - with: - tool: sccache - checksum: true + # - name: Install sccache + # uses: taiki-e/install-action@v2.33.28 + # with: + # tool: sccache + # checksum: true + + - name: Install rust cache + uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Install cargo-hack uses: taiki-e/install-action@v2.33.28 @@ -181,7 +186,7 @@ jobs: env: # Use `sccache` for caching compilation artifacts - RUSTC_WRAPPER: sccache + # RUSTC_WRAPPER: sccache RUSTFLAGS: "-D warnings" strategy: @@ -229,11 +234,16 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Install sccache - uses: taiki-e/install-action@v2.33.28 - with: - tool: sccache - checksum: true + # - name: Install sccache + # uses: taiki-e/install-action@v2.33.28 + # with: + # tool: sccache + # checksum: true + + - name: Install rust cache + uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Install cargo-hack uses: taiki-e/install-action@v2.33.28 @@ -259,7 +269,7 @@ jobs: - name: Run clippy shell: bash - run: just clippy --jobs 2 + run: just clippy - name: Check Cargo.lock changed if: ${{ (github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name) }} @@ -315,7 +325,9 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install rust cache - uses: Swatinem/rust-cache@v2.7.0 + uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Install just uses: taiki-e/install-action@v2.41.10 diff --git a/.github/workflows/CI-push.yml b/.github/workflows/CI-push.yml index e17ce46d850..306e6812594 100644 --- a/.github/workflows/CI-push.yml +++ b/.github/workflows/CI-push.yml @@ -43,7 +43,7 @@ jobs: env: # Use `sccache` for caching compilation artifacts - RUSTC_WRAPPER: sccache + # RUSTC_WRAPPER: sccache RUSTFLAGS: "-D warnings" strategy: @@ -78,15 +78,15 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Install sccache - uses: taiki-e/install-action@v2.33.28 - with: - tool: sccache - checksum: true - - # - uses: Swatinem/rust-cache@v2.7.0 + # - name: Install sccache + # uses: taiki-e/install-action@v2.33.28 # with: - # save-if: ${{ github.event_name == 'push' }} + # tool: sccache + # checksum: true + + - uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: ${{ github.event_name == 'push' }} - name: Install cargo-hack uses: baptiste0928/cargo-install@v2.2.0 @@ -140,7 +140,7 @@ jobs: env: # Use `sccache` for caching compilation artifacts - RUSTC_WRAPPER: sccache + # RUSTC_WRAPPER: sccache RUSTFLAGS: "-D warnings" strategy: @@ -170,11 +170,11 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - name: Install sccache - uses: taiki-e/install-action@v2.33.28 - with: - tool: sccache - checksum: true + # - name: Install sccache + # uses: taiki-e/install-action@v2.33.28 + # with: + # tool: sccache + # checksum: true - name: Install cargo-hack uses: baptiste0928/cargo-install@v2.2.0 @@ -196,13 +196,13 @@ jobs: # with: # crate: cargo-nextest - # - uses: Swatinem/rust-cache@v2.7.0 - # with: - # save-if: ${{ github.event_name == 'push' }} + - uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: ${{ github.event_name == 'push' }} - name: Run clippy shell: bash - run: just clippy --jobs 2 + run: just clippy - name: Cargo hack if: ${{ github.event_name == 'push' }} @@ -249,7 +249,7 @@ jobs: repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install rust cache - uses: Swatinem/rust-cache@v2.7.0 + uses: Swatinem/rust-cache@v2.7.7 - name: Run cargo check enabling only the release and v2 features shell: bash diff --git a/.github/workflows/connector-sanity-tests.yml b/.github/workflows/connector-sanity-tests.yml index 48e6a946a45..1f10828de9d 100644 --- a/.github/workflows/connector-sanity-tests.yml +++ b/.github/workflows/connector-sanity-tests.yml @@ -86,7 +86,9 @@ jobs: with: toolchain: stable 2 weeks ago - - uses: Swatinem/rust-cache@v2.7.0 + - uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Decrypt connector auth file env: diff --git a/.github/workflows/connector-ui-sanity-tests.yml b/.github/workflows/connector-ui-sanity-tests.yml index f3d4635ab11..9cad6191f06 100644 --- a/.github/workflows/connector-ui-sanity-tests.yml +++ b/.github/workflows/connector-ui-sanity-tests.yml @@ -122,7 +122,9 @@ jobs: toolchain: stable - name: Build and Cache Rust Dependencies - uses: Swatinem/rust-cache@v2.7.0 + uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Install Diesel CLI with Postgres Support uses: baptiste0928/cargo-install@v2.2.0 diff --git a/.github/workflows/cypress-tests-runner.yml b/.github/workflows/cypress-tests-runner.yml index 72429627ff7..4de046499ab 100644 --- a/.github/workflows/cypress-tests-runner.yml +++ b/.github/workflows/cypress-tests-runner.yml @@ -170,13 +170,6 @@ jobs: tool: sccache checksum: true - - name: Install cargo-nextest - if: ${{ env.RUN_TESTS == 'true' }} - uses: taiki-e/install-action@v2.41.10 - with: - tool: cargo-nextest - checksum: true - - name: Install Diesel CLI if: ${{ env.RUN_TESTS == 'true' }} uses: baptiste0928/cargo-install@v3.1.1 @@ -266,3 +259,211 @@ jobs: path: | cypress-tests/cypress/reports/ retention-days: 1 + + runner_v2: + name: Run Cypress tests on v2 and generate coverage report + runs-on: hyperswitch-runners + env: + CODECOV_FILE: "lcov.info" + + services: + redis: + image: "public.ecr.aws/docker/library/redis:alpine" + options: >- + --health-cmd "redis-cli ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 6379:6379 + postgres: + image: "public.ecr.aws/docker/library/postgres:alpine" + env: + POSTGRES_USER: db_user + POSTGRES_PASSWORD: db_pass + POSTGRES_DB: hyperswitch_db + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + steps: + - name: Skip tests for PRs from forks + shell: bash + if: ${{ env.RUN_TESTS == 'false' }} + run: echo 'Skipping tests for PRs from forks' + + - name: Checkout repository + if: ${{ env.RUN_TESTS == 'true' }} + uses: actions/checkout@v4 + + - name: Download Encrypted TOML from S3 and Decrypt + if: ${{ env.RUN_TESTS == 'true' }} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.CONNECTOR_CREDS_AWS_ACCESS_KEY_ID }} + AWS_REGION: ${{ secrets.CONNECTOR_CREDS_AWS_REGION }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.CONNECTOR_CREDS_AWS_SECRET_ACCESS_KEY }} + 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: "aa328308-b34e-41b7-a590-4fe45cfe7991.json.gpg" + shell: bash + run: | + mkdir -p ".github/secrets" ".github/test" + + aws s3 cp "${CONNECTOR_CREDS_S3_BUCKET_URI}/${S3_SOURCE_FILE_NAME}" ".github/secrets/${DESTINATION_FILE_NAME}" + gpg --quiet --batch --yes --decrypt --passphrase="${CONNECTOR_AUTH_PASSPHRASE}" --output ".github/test/creds.json" ".github/secrets/${DESTINATION_FILE_NAME}" + + - name: Set paths in env + if: ${{ env.RUN_TESTS == 'true' }} + shell: bash + run: | + echo "CYPRESS_CONNECTOR_AUTH_FILE_PATH=${{ github.workspace }}/.github/test/creds.json" >> $GITHUB_ENV + + - name: Fetch keys + if: ${{ env.RUN_TESTS == 'true' }} + env: + TOML_PATH: "./config/development.toml" + run: | + LOCAL_ADMIN_API_KEY=$(yq '.secrets.admin_api_key' ${TOML_PATH}) + echo "CYPRESS_ADMINAPIKEY=${LOCAL_ADMIN_API_KEY}" >> $GITHUB_ENV + + - name: Install mold linker + if: ${{ runner.os == 'Linux' && env.RUN_TESTS == 'true' }} + uses: rui314/setup-mold@v1 + with: + make-default: true + + - name: Install Rust + if: ${{ env.RUN_TESTS == 'true' }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable 2 weeks ago + components: llvm-tools-preview + + - name: Install sccache + if: ${{ env.RUN_TESTS == 'true' }} + uses: taiki-e/install-action@v2.41.10 + with: + tool: sccache + checksum: true + + - name: Install Diesel CLI + if: ${{ env.RUN_TESTS == 'true' }} + uses: baptiste0928/cargo-install@v3.1.1 + with: + crate: diesel_cli + features: postgres + args: --no-default-features + + - name: Install grcov + if: ${{ env.RUN_TESTS == 'true' }} + uses: taiki-e/install-action@v2.41.10 + with: + tool: grcov + checksum: true + + - name: Install Just + if: ${{ env.RUN_TESTS == 'true' }} + uses: taiki-e/install-action@v2.41.10 + with: + tool: just + checksum: true + + - name: Install Node.js + if: ${{ env.RUN_TESTS == 'true' }} + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install Cypress and dependencies + if: ${{ env.RUN_TESTS == 'true' }} + run: | + npm ci --prefix ./cypress-tests-v2 + + - name: Run database migrations + if: ${{ env.RUN_TESTS == 'true' }} + shell: bash + env: + DATABASE_URL: postgres://db_user:db_pass@localhost:5432/hyperswitch_db + run: just migrate_v2 run --locked-schema + + - name: Insert card info into the database + if: ${{ env.RUN_TESTS == 'true' }} + run: | + PGPASSWORD=db_pass psql --host=localhost --port=5432 --username=db_user --dbname=hyperswitch_db --command "\copy cards_info FROM '.github/data/cards_info.csv' DELIMITER ',' CSV HEADER;" + + - name: Build project + if: ${{ env.RUN_TESTS == 'true' }} + env: + RUSTFLAGS: "-Cinstrument-coverage" + run: just build_v2 --jobs 3 + + - name: Setup Local Server + if: ${{ env.RUN_TESTS == 'true' }} + env: + LLVM_PROFILE_FILE: "coverage.profraw" + run: | + # Start the server in the background + target/debug/router & + + SERVER_PID=$! + echo "PID=${SERVER_PID}" >> $GITHUB_ENV + + # Wait for the server to start in port 8080 + COUNT=0 + while ! nc -z localhost 8080; do + if [ $COUNT -gt 12 ]; then # Wait for up to 2 minutes (12 * 10 seconds) + echo "Server did not start within a reasonable time. Exiting." + kill ${SERVER_PID} + exit 1 + else + COUNT=$((COUNT+1)) + sleep 10 + fi + done + + - name: Run Cypress tests + if: ${{ env.RUN_TESTS == 'true' }} + env: + CYPRESS_BASEURL: "http://localhost:8080" + ROUTER__SERVER__WORKERS: 4 + shell: bash -leuo pipefail {0} + continue-on-error: true + # We aren't specifying `command` and `jobs` arguments currently + run: scripts/execute_cypress.sh "" "" "cypress-tests-v2" + + - name: Stop running server + if: ${{ env.RUN_TESTS == 'true' }} && always() + run: | + kill "${{ env.PID }}" + + - name: Upload Cypress test results + if: env.RUN_TESTS == 'true' && failure() + uses: actions/upload-artifact@v4 + with: + name: cypress-v2-test-results + path: | + cypress-tests-v2/cypress/reports/ + retention-days: 1 + + # Notes: + # - The `router` process must be killed (using SIGINT/SIGTERM) to generate the `coverage.profraw` file, otherwise the coverage will only be generated for the buildscripts + # - Trying to generate branch coverage using "-Z coverage-options=branch" currently fails. Both grcov and cargo-llvm-cov crash when trying + # to process the generated `.profraw` files. + # - --keep-only argument is used to exclude external crates in generated lcov.info file (~500MiB -> ~70MiB) + - name: Process coverage report + if: ${{ env.RUN_TESTS == 'true' && github.event_name != 'merge_group' }} + run: grcov . --source-dir . --output-types lcov --output-path ${{ env.CODECOV_FILE }} --binary-path ./target/debug --keep-only "crates/*" + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + if: ${{ env.RUN_TESTS == 'true' && github.event_name != 'merge_group'}} + with: + token: ${{ secrets.CODECOV_TOKEN }} + files: ${{ env.CODECOV_FILE }} + disable_search: true \ No newline at end of file diff --git a/.github/workflows/postman-collection-runner.yml b/.github/workflows/postman-collection-runner.yml index b8ce65f4b6c..bc6bd7849fe 100644 --- a/.github/workflows/postman-collection-runner.yml +++ b/.github/workflows/postman-collection-runner.yml @@ -92,7 +92,9 @@ jobs: - name: Build and Cache Rust Dependencies if: ${{ ((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')}} - uses: Swatinem/rust-cache@v2.7.0 + uses: Swatinem/rust-cache@v2.7.7 + with: + save-if: false - name: Install Protoc if: ${{ ((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')}} diff --git a/.gitignore b/.gitignore index dcbeddf7ada..d53145b33ee 100644 --- a/.gitignore +++ b/.gitignore @@ -241,6 +241,7 @@ $RECYCLE.BIN/ # hyperswitch Project specific excludes # code coverage report *.profraw +lcov.info html/ coverage.json # other diff --git a/CHANGELOG.md b/CHANGELOG.md index f8594f6be28..8ed7f89e30e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,70 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2025.01.31.0 + +### Miscellaneous Tasks + +- **postman:** Update Postman collection files ([`3af63a7`](https://github.com/juspay/hyperswitch/commit/3af63a7c92033cd1aeedf90e31209de088e5b78d)) + +**Full Changelog:** [`2025.01.30.0...2025.01.31.0`](https://github.com/juspay/hyperswitch/compare/2025.01.30.0...2025.01.31.0) + +- - - + +## 2025.01.30.0 + +### Features + +- **connector:** Add template code for chargebee ([#7036](https://github.com/juspay/hyperswitch/pull/7036)) ([`ad5491f`](https://github.com/juspay/hyperswitch/commit/ad5491f15bd8f61b2a918f584fe85132986176ad)) +- **router:** Add accept-language from request headers into browser-info ([#7074](https://github.com/juspay/hyperswitch/pull/7074)) ([`5381eb9`](https://github.com/juspay/hyperswitch/commit/5381eb992228164b552260c7ebb8a4cdbc1b3cb3)) + +### Refactors + +- **euclid:** Update proto file for elimination routing ([#7032](https://github.com/juspay/hyperswitch/pull/7032)) ([`275958a`](https://github.com/juspay/hyperswitch/commit/275958af14d0eb4385c995308fbf958c6b620e4f)) + +### Miscellaneous Tasks + +- Run clippy with default number of jobs in github workflows ([#7088](https://github.com/juspay/hyperswitch/pull/7088)) ([`337095b`](https://github.com/juspay/hyperswitch/commit/337095bce8c57be9a9a2ff8356ca9b70917b9851)) + +**Full Changelog:** [`2025.01.29.0...2025.01.30.0`](https://github.com/juspay/hyperswitch/compare/2025.01.29.0...2025.01.30.0) + +- - - + +## 2025.01.29.0 + +### Bug Fixes + +- **multitenancy:** Add a fallback for get commands in redis ([#7043](https://github.com/juspay/hyperswitch/pull/7043)) ([`5707297`](https://github.com/juspay/hyperswitch/commit/5707297621538ccf47f7314ca564783d6f289317)) + +### Refactors + +- **currency_conversion:** Re frame the currency_conversion crate to make api calls on background thread ([#6906](https://github.com/juspay/hyperswitch/pull/6906)) ([`858866f`](https://github.com/juspay/hyperswitch/commit/858866f9f361c16b76ed79b42814b648f2050f08)) +- **router:** Prioritise `connector_mandate_id` over `network_transaction_id` during MITs ([#7081](https://github.com/juspay/hyperswitch/pull/7081)) ([`5ff57fa`](https://github.com/juspay/hyperswitch/commit/5ff57fa3374cd4bb6ff211057d7280b6fd1ea321)) + +### Miscellaneous Tasks + +- Fix `toml` format to address wasm build failure ([#6967](https://github.com/juspay/hyperswitch/pull/6967)) ([`ecab2b1`](https://github.com/juspay/hyperswitch/commit/ecab2b1f512eb7e78ca2e75c20b3adc753b97a2f)) +- Add stripe to network transaction id support ([#7096](https://github.com/juspay/hyperswitch/pull/7096)) ([`4cf011f`](https://github.com/juspay/hyperswitch/commit/4cf011f9886de419b48576f5d4ef77fdcfc2d4ad)) + +**Full Changelog:** [`2025.01.27.0...2025.01.29.0`](https://github.com/juspay/hyperswitch/compare/2025.01.27.0...2025.01.29.0) + +- - - + +## 2025.01.27.0 + +### Bug Fixes + +- **connectors:** [worldpay] send decoded token for ApplePay ([#7069](https://github.com/juspay/hyperswitch/pull/7069)) ([`7fd3551`](https://github.com/juspay/hyperswitch/commit/7fd3551afd7122ed28fe5532639e4a256863de6b)) +- **cypress:** Uncaught exceptions thrown by `hyperswitch.io` ([#7092](https://github.com/juspay/hyperswitch/pull/7092)) ([`cf82861`](https://github.com/juspay/hyperswitch/commit/cf82861e855bbd055fcbfc2367b23eaa58d8f842)) + +### Refactors + +- **cypress:** Move memory cache tests out of payment for misc ([#6992](https://github.com/juspay/hyperswitch/pull/6992)) ([`4382fc6`](https://github.com/juspay/hyperswitch/commit/4382fc650ae586e5244f2c68ec0fba536caa88a9)) + +**Full Changelog:** [`2025.01.23.0...2025.01.27.0`](https://github.com/juspay/hyperswitch/compare/2025.01.23.0...2025.01.27.0) + +- - - + ## 2025.01.23.0 ### Features diff --git a/README.md b/README.md index c09176b172a..5b5518d31fc 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,10 @@ Single API to access the payments ecosystem and its features + +

diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index b7a6c3a203c..92394521a2c 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -5696,6 +5696,11 @@ "type": "string", "description": "The device model of the client", "nullable": true + }, + "accept_language": { + "type": "string", + "description": "Accept-language of the browser", + "nullable": true } } }, diff --git a/api-reference/mint.json b/api-reference/mint.json index 1130da2ffb0..a134b3c5b2b 100644 --- a/api-reference/mint.json +++ b/api-reference/mint.json @@ -15,10 +15,6 @@ } }, "tabs": [ - { - "name": "API Reference", - "url": "api-reference" - }, { "name": "Locker API Reference", "url": "locker-api-reference" @@ -38,212 +34,222 @@ ] }, { - "group": "Payments", - "pages": [ - "api-reference/payments/payments--create", - "api-reference/payments/payments--update", - "api-reference/payments/payments--confirm", - "api-reference/payments/payments--retrieve", - "api-reference/payments/payments--cancel", - "api-reference/payments/payments--capture", - "api-reference/payments/payments--incremental-authorization", - "api-reference/payments/payments--session-token", - "api-reference/payments/payments-link--retrieve", - "api-reference/payments/payments--list", - "api-reference/payments/payments--external-3ds-authentication", - "api-reference/payments/payments--complete-authorize" - ] - }, - { - "group": "Payment Methods", - "pages": [ - "api-reference/payment-methods/paymentmethods--create", - "api-reference/payment-methods/payment-method--retrieve", - "api-reference/payment-methods/payment-method--update", - "api-reference/payment-methods/payment-method--delete", - "api-reference/payment-methods/payment-method--set-default-payment-method-for-customer", - "api-reference/payment-methods/list-payment-methods-for-a-merchant", - "api-reference/payment-methods/list-customer-saved-payment-methods-for-a-payment", - "api-reference/payment-methods/list-payment-methods-for-a-customer", - "api-reference/customer-set-default-payment-method/customers--set-default-payment-method" - ] - }, - { - "group": "Customers", - "pages": [ - "api-reference/customers/customers--create", - "api-reference/customers/customers--retrieve", - "api-reference/customers/customers--update", - "api-reference/customers/customers--delete", - "api-reference/customers/customers--list" - ] - }, - { - "group": "Mandates", - "pages": [ - "api-reference/mandates/mandates--revoke-mandate", - "api-reference/mandates/mandates--retrieve-mandate", - "api-reference/mandates/mandates--customer-mandates-list" - ] - }, - { - "group": "Refunds", - "pages": [ - "api-reference/refunds/refunds--create", - "api-reference/refunds/refunds--update", - "api-reference/refunds/refunds--retrieve", - "api-reference/refunds/refunds--list" - ] - }, - { - "group": "Disputes", - "pages": [ - "api-reference/disputes/disputes--retrieve", - "api-reference/disputes/disputes--list" - ] - }, - { - "group": "Organization", - "pages": [ - "api-reference/organization/organization--create", - "api-reference/organization/organization--retrieve", - "api-reference/organization/organization--update" - ] - }, - { - "group": "Merchant Account", - "pages": [ - "api-reference/merchant-account/merchant-account--create", - "api-reference/merchant-account/merchant-account--retrieve", - "api-reference/merchant-account/merchant-account--update", - "api-reference/merchant-account/merchant-account--delete", - "api-reference/merchant-account/merchant-account--kv-status" - ] - }, - { - "group": "Business Profile", - "pages": [ - "api-reference/business-profile/business-profile--create", - "api-reference/business-profile/business-profile--update", - "api-reference/business-profile/business-profile--retrieve", - "api-reference/business-profile/business-profile--delete", - "api-reference/business-profile/business-profile--list" - ] - }, - { - "group": "API Key", + "group": "API Reference", "pages": [ - "api-reference/api-key/api-key--create", - "api-reference/api-key/api-key--retrieve", - "api-reference/api-key/api-key--update", - "api-reference/api-key/api-key--revoke", - "api-reference/api-key/api-key--list" + { + "group": "Payments", + "pages": [ + "api-reference/payments/payments--create", + "api-reference/payments/payments--update", + "api-reference/payments/payments--confirm", + "api-reference/payments/payments--retrieve", + "api-reference/payments/payments--cancel", + "api-reference/payments/payments--capture", + "api-reference/payments/payments--incremental-authorization", + "api-reference/payments/payments--session-token", + "api-reference/payments/payments-link--retrieve", + "api-reference/payments/payments--list", + "api-reference/payments/payments--external-3ds-authentication", + "api-reference/payments/payments--complete-authorize" + ] + }, + { + "group": "Payment Methods", + "pages": [ + "api-reference/payment-methods/paymentmethods--create", + "api-reference/payment-methods/payment-method--retrieve", + "api-reference/payment-methods/payment-method--update", + "api-reference/payment-methods/payment-method--delete", + "api-reference/payment-methods/payment-method--set-default-payment-method-for-customer", + "api-reference/payment-methods/list-payment-methods-for-a-merchant", + "api-reference/payment-methods/list-customer-saved-payment-methods-for-a-payment", + "api-reference/payment-methods/list-payment-methods-for-a-customer", + "api-reference/customer-set-default-payment-method/customers--set-default-payment-method" + ] + }, + { + "group": "Customers", + "pages": [ + "api-reference/customers/customers--create", + "api-reference/customers/customers--retrieve", + "api-reference/customers/customers--update", + "api-reference/customers/customers--delete", + "api-reference/customers/customers--list" + ] + }, + { + "group": "Mandates", + "pages": [ + "api-reference/mandates/mandates--revoke-mandate", + "api-reference/mandates/mandates--retrieve-mandate", + "api-reference/mandates/mandates--customer-mandates-list" + ] + }, + { + "group": "Refunds", + "pages": [ + "api-reference/refunds/refunds--create", + "api-reference/refunds/refunds--update", + "api-reference/refunds/refunds--retrieve", + "api-reference/refunds/refunds--list" + ] + }, + { + "group": "Disputes", + "pages": [ + "api-reference/disputes/disputes--retrieve", + "api-reference/disputes/disputes--list" + ] + }, + { + "group": "Organization", + "pages": [ + "api-reference/organization/organization--create", + "api-reference/organization/organization--retrieve", + "api-reference/organization/organization--update" + ] + }, + { + "group": "Merchant Account", + "pages": [ + "api-reference/merchant-account/merchant-account--create", + "api-reference/merchant-account/merchant-account--retrieve", + "api-reference/merchant-account/merchant-account--update", + "api-reference/merchant-account/merchant-account--delete", + "api-reference/merchant-account/merchant-account--kv-status" + ] + }, + { + "group": "Business Profile", + "pages": [ + "api-reference/business-profile/business-profile--create", + "api-reference/business-profile/business-profile--update", + "api-reference/business-profile/business-profile--retrieve", + "api-reference/business-profile/business-profile--delete", + "api-reference/business-profile/business-profile--list" + ] + }, + { + "group": "API Key", + "pages": [ + "api-reference/api-key/api-key--create", + "api-reference/api-key/api-key--retrieve", + "api-reference/api-key/api-key--update", + "api-reference/api-key/api-key--revoke", + "api-reference/api-key/api-key--list" + ] + }, + { + "group": "Merchant Connector Account", + "pages": [ + "api-reference/merchant-connector-account/merchant-connector--create", + "api-reference/merchant-connector-account/merchant-connector--retrieve", + "api-reference/merchant-connector-account/merchant-connector--update", + "api-reference/merchant-connector-account/merchant-connector--delete", + "api-reference/merchant-connector-account/merchant-connector--list" + ] + }, + { + "group": "Payouts", + "pages": [ + "api-reference/payouts/payouts--create", + "api-reference/payouts/payouts--update", + "api-reference/payouts/payouts--cancel", + "api-reference/payouts/payouts--fulfill", + "api-reference/payouts/payouts--confirm", + "api-reference/payouts/payouts--retrieve", + "api-reference/payouts/payouts--list", + "api-reference/payouts/payouts--list-filters", + "api-reference/payouts/payouts--filter" + ] + }, + { + "group": "Event", + "pages": [ + "api-reference/event/events--list", + "api-reference/event/events--delivery-attempt-list", + "api-reference/event/events--manual-retry" + ] + }, + { + "group": "GSM (Global Status Mapping)", + "pages": [ + "api-reference/gsm/gsm--create", + "api-reference/gsm/gsm--get", + "api-reference/gsm/gsm--update", + "api-reference/gsm/gsm--delete" + ] + }, + { + "group": "Poll", + "pages": ["api-reference/poll/poll--retrieve-poll-status"] + }, + { + "group": "Blocklist", + "pages": [ + "api-reference/blocklist/get-blocklist", + "api-reference/blocklist/post-blocklist", + "api-reference/blocklist/delete-blocklist", + "api-reference/blocklist/post-blocklisttoggle" + ] + }, + { + "group": "Routing", + "pages": [ + "api-reference/routing/routing--list", + "api-reference/routing/routing--create", + "api-reference/routing/routing--retrieve-config", + "api-reference/routing/routing--deactivate", + "api-reference/routing/routing--retrieve-default-config", + "api-reference/routing/routing--update-default-config", + "api-reference/routing/routing--retrieve-default-for-profile", + "api-reference/routing/routing--update-default-for-profile", + "api-reference/routing/routing--retrieve", + "api-reference/routing/routing--activate-config" + ] + }, + { + "group": "Relay", + "pages": [ + "api-reference/relay/relay", + "api-reference/relay/relay--retrieve" + ] + }, + { + "group": "Schemas", + "pages": ["api-reference/schemas/outgoing--webhook"] + } ] }, - { - "group": "Merchant Connector Account", - "pages": [ - "api-reference/merchant-connector-account/merchant-connector--create", - "api-reference/merchant-connector-account/merchant-connector--retrieve", - "api-reference/merchant-connector-account/merchant-connector--update", - "api-reference/merchant-connector-account/merchant-connector--delete", - "api-reference/merchant-connector-account/merchant-connector--list" - ] - }, - { - "group": "Payouts", - "pages": [ - "api-reference/payouts/payouts--create", - "api-reference/payouts/payouts--update", - "api-reference/payouts/payouts--cancel", - "api-reference/payouts/payouts--fulfill", - "api-reference/payouts/payouts--confirm", - "api-reference/payouts/payouts--retrieve", - "api-reference/payouts/payouts--list", - "api-reference/payouts/payouts--list-filters", - "api-reference/payouts/payouts--filter" - ] - }, - { - "group": "Event", - "pages": [ - "api-reference/event/events--list", - "api-reference/event/events--delivery-attempt-list", - "api-reference/event/events--manual-retry" - ] - }, - { - "group": "GSM (Global Status Mapping)", - "pages": [ - "api-reference/gsm/gsm--create", - "api-reference/gsm/gsm--get", - "api-reference/gsm/gsm--update", - "api-reference/gsm/gsm--delete" - ] - }, - { - "group": "Poll", - "pages": ["api-reference/poll/poll--retrieve-poll-status"] - }, { "group": "Hyperswitch Card Vault", "pages": ["locker-api-reference/overview"] }, { - "group": "Locker - Health", - "pages": ["locker-api-reference/locker-health/get-health"] - }, - { - "group": "Locker - Key Custodian", - "pages": [ - "locker-api-reference/key-custodian/provide-key-1", - "locker-api-reference/key-custodian/provide-key-2", - "locker-api-reference/key-custodian/unlock-the-locker" - ] - }, - { - "group": "Locker - Cards", + "group": "API Reference", "pages": [ - "locker-api-reference/cards/add-data-in-locker", - "locker-api-reference/cards/delete-data-from-locker", - "locker-api-reference/cards/retrieve-data-from-locker", - "locker-api-reference/cards/get-or-insert-the-card-fingerprint" + { + "group": "Locker - Health", + "pages": ["locker-api-reference/locker-health/get-health"] + }, + { + "group": "Locker - Key Custodian", + "pages": [ + "locker-api-reference/key-custodian/provide-key-1", + "locker-api-reference/key-custodian/provide-key-2", + "locker-api-reference/key-custodian/unlock-the-locker" + ] + }, + { + "group": "Locker - Cards", + "pages": [ + "locker-api-reference/cards/add-data-in-locker", + "locker-api-reference/cards/delete-data-from-locker", + "locker-api-reference/cards/retrieve-data-from-locker", + "locker-api-reference/cards/get-or-insert-the-card-fingerprint" + ] + } ] - }, - { - "group": "Blocklist", - "pages": [ - "api-reference/blocklist/get-blocklist", - "api-reference/blocklist/post-blocklist", - "api-reference/blocklist/delete-blocklist", - "api-reference/blocklist/post-blocklisttoggle" - ] - }, - { - "group": "Routing", - "pages": [ - "api-reference/routing/routing--list", - "api-reference/routing/routing--create", - "api-reference/routing/routing--retrieve-config", - "api-reference/routing/routing--deactivate", - "api-reference/routing/routing--retrieve-default-config", - "api-reference/routing/routing--update-default-config", - "api-reference/routing/routing--retrieve-default-for-profile", - "api-reference/routing/routing--update-default-for-profile", - "api-reference/routing/routing--retrieve", - "api-reference/routing/routing--activate-config" - ] - }, - { - "group": "Relay", - "pages": [ - "api-reference/relay/relay", - "api-reference/relay/relay--retrieve" - ] - }, - { - "group": "Schemas", - "pages": ["api-reference/schemas/outgoing--webhook"] } ], "footerSocials": { @@ -256,12 +262,12 @@ }, "analytics": { "gtm": { - "tagId": "GTM-PLBNKQFQ" + "tagId": "GTM-PLBNKQFQ" } }, "analytics": { "mixpanel": { - "projectToken": "b00355f29d9548d1333608df71d5d53d" + "projectToken": "b00355f29d9548d1333608df71d5d53d" } } } diff --git a/config/config.example.toml b/config/config.example.toml index df64cb54e4d..75374e2a381 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -74,13 +74,10 @@ max_feed_count = 200 # The maximum number of frames that will be fe # This section provides configs for currency conversion api [forex_api] -call_delay = 21600 # Api calls are made after every 6 hrs -local_fetch_retry_count = 5 # Fetch from Local cache has retry count as 5 -local_fetch_retry_delay = 1000 # Retry delay for checking write condition -api_timeout = 20000 # Api timeouts once it crosses 20000 ms -api_key = "YOUR API KEY HERE" # Api key for making request to foreign exchange Api -fallback_api_key = "YOUR API KEY" # Api key for the fallback service -redis_lock_timeout = 26000 # Redis remains write locked for 26000 ms once the acquire_redis_lock is called +call_delay = 21600 # Expiration time for data in cache as well as redis in seconds +api_key = "" # Api key for making request to foreign exchange Api +fallback_api_key = "" # Api key for the fallback service +redis_lock_timeout = 100 # Redis remains write locked for 100 s once the acquire_redis_lock is called # Logging configuration. Logging can be either to file or console or both. @@ -196,6 +193,7 @@ bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" boku.base_url = "https://$-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml index 811c6e4d0f5..4e5fa3dba44 100644 --- a/config/deployments/env_specific.toml +++ b/config/deployments/env_specific.toml @@ -104,13 +104,10 @@ bucket_name = "bucket" # The AWS S3 bucket name for file storage # This section provides configs for currency conversion api [forex_api] -call_delay = 21600 # Api calls are made after every 6 hrs -local_fetch_retry_count = 5 # Fetch from Local cache has retry count as 5 -local_fetch_retry_delay = 1000 # Retry delay for checking write condition -api_timeout = 20000 # Api timeouts once it crosses 20000 ms -api_key = "YOUR API KEY HERE" # Api key for making request to foreign exchange Api -fallback_api_key = "YOUR API KEY" # Api key for the fallback service -redis_lock_timeout = 26000 # Redis remains write locked for 26000 ms once the acquire_redis_lock is called +call_delay = 21600 # Expiration time for data in cache as well as redis in seconds +api_key = "" # Api key for making request to foreign exchange Api +fallback_api_key = "" # Api key for the fallback service +redis_lock_timeout = 100 # Redis remains write locked for 100 s once the acquire_redis_lock is called [jwekey] # 3 priv/pub key pair vault_encryption_key = "" # public key in pem format, corresponding private key in rust locker diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml index b6e487e5a3b..d606f192e4e 100644 --- a/config/deployments/integration_test.toml +++ b/config/deployments/integration_test.toml @@ -39,6 +39,7 @@ bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" boku.base_url = "https://$-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" diff --git a/config/deployments/production.toml b/config/deployments/production.toml index 3537834fd07..ff5abd3fb03 100644 --- a/config/deployments/production.toml +++ b/config/deployments/production.toml @@ -43,6 +43,7 @@ bluesnap.secondary_base_url = "https://pay.bluesnap.com/" boku.base_url = "https://country-api4-stage.boku.com" braintree.base_url = "https://payments.braintree-api.com/graphql" cashtocode.base_url = "https://cluster14.api.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business.cryptopay.me/" @@ -191,7 +192,7 @@ card.credit = { connector_list = "cybersource" } # Update Mandate sup card.debit = { connector_list = "cybersource" } # Update Mandate supported payment method type and connector for card [network_transaction_id_supported_connectors] -connector_list = "adyen" +connector_list = "adyen,stripe" [payouts] payout_eligibility = true # Defaults the eligibility of a payout method to true in case connector does not provide checks for payout eligibility diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml index 7242f263672..208621433bb 100644 --- a/config/deployments/sandbox.toml +++ b/config/deployments/sandbox.toml @@ -44,6 +44,7 @@ boku.base_url = "https://$-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" checkout.base_url = "https://api.sandbox.checkout.com/" +chargebee.base_url = "https://$.chargebee.com/api/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" diff --git a/config/development.toml b/config/development.toml index 3f793ad426d..dc4773db908 100644 --- a/config/development.toml +++ b/config/development.toml @@ -78,12 +78,9 @@ ttl_for_storage_in_secs = 220752000 [forex_api] call_delay = 21600 -local_fetch_retry_count = 5 -local_fetch_retry_delay = 1000 -api_timeout = 20000 -api_key = "YOUR API KEY HERE" -fallback_api_key = "YOUR API KEY HERE" -redis_lock_timeout = 26000 +api_key = "" +fallback_api_key = "" +redis_lock_timeout = 100 [jwekey] vault_encryption_key = "" @@ -215,6 +212,7 @@ bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" boku.base_url = "https://$-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 4296a5931dc..656d4fa7ecb 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -31,12 +31,9 @@ pool_size = 5 [forex_api] call_delay = 21600 -local_fetch_retry_count = 5 -local_fetch_retry_delay = 1000 -api_timeout = 20000 -api_key = "YOUR API KEY HERE" -fallback_api_key = "YOUR API KEY HERE" -redis_lock_timeout = 26000 +api_key = "" +fallback_api_key = "" +redis_lock_timeout = 100 [replica_database] username = "db_user" @@ -128,6 +125,7 @@ bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" boku.base_url = "https://$-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" diff --git a/crates/analytics/docs/README.md b/crates/analytics/docs/README.md index e24dc6c5af7..71190613a10 100644 --- a/crates/analytics/docs/README.md +++ b/crates/analytics/docs/README.md @@ -115,8 +115,8 @@ To configure the Forex APIs, update the `config/development.toml` or `config/doc ```toml [forex_api] -api_key = "YOUR API KEY HERE" # Replace the placeholder with your Primary API Key -fallback_api_key = "YOUR API KEY HERE" # Replace the placeholder with your Fallback API Key +api_key = "" +fallback_api_key = "" ``` ### Important Note ```bash @@ -159,4 +159,4 @@ To view the data on the OpenSearch dashboard perform the following steps: - Select a time field that will be used for time-based queries - Save the index pattern -Now, head on to `Discover` under the `OpenSearch Dashboards` tab, to select the newly created index pattern and query the data \ No newline at end of file +Now, head on to `Discover` under the `OpenSearch Dashboards` tab, to select the newly created index pattern and query the data diff --git a/crates/common_enums/src/connector_enums.rs b/crates/common_enums/src/connector_enums.rs index 0402ae06459..288520722c3 100644 --- a/crates/common_enums/src/connector_enums.rs +++ b/crates/common_enums/src/connector_enums.rs @@ -65,6 +65,7 @@ pub enum RoutableConnectors { Boku, Braintree, Cashtocode, + // Chargebee, Checkout, Coinbase, Cryptopay, @@ -199,6 +200,7 @@ pub enum Connector { Boku, Braintree, Cashtocode, + // Chargebee, Checkout, Coinbase, Cryptopay, @@ -350,6 +352,7 @@ impl Connector { | Self::Boku | Self::Braintree | Self::Cashtocode + // | Self::Chargebee | Self::Coinbase | Self::Cryptopay | Self::Deutschebank diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 9e71ca76733..4e88d5c0fde 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -1408,6 +1408,9 @@ pub struct BrowserInformation { /// The device model of the client pub device_model: Option, + + /// Accept-language of the browser + pub accept_language: Option, } #[cfg(feature = "v2")] diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml index 35f2f14c748..5b963e07801 100644 --- a/crates/connector_configs/toml/production.toml +++ b/crates/connector_configs/toml/production.toml @@ -1478,6 +1478,7 @@ key2="Certificate Key" payment_method_type = "Visa" [jpmorgan.connector_auth.BodyKey] api_key="Access Token" +key1="Client Secret" [klarna] [[klarna.pay_later]] diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml index ed903812219..50c13dc8596 100644 --- a/crates/connector_configs/toml/sandbox.toml +++ b/crates/connector_configs/toml/sandbox.toml @@ -1714,6 +1714,7 @@ key2="Certificate Key" payment_method_type = "Visa" [jpmorgan.connector_auth.BodyKey] api_key="Access Token" +key1="Client Secret" [klarna] [[klarna.pay_later]] @@ -4374,7 +4375,7 @@ placeholder="Enter locale" required=true type="Text" -[[ctp_mastercard.metadata.card_brands]] +[ctp_mastercard.metadata.card_brands] name="card_brands" label="Card Brands" placeholder="Enter Card Brands" @@ -4382,28 +4383,28 @@ required=true type="MultiSelect" options=["visa","mastercard"] -[[ctp_mastercard.metadata.acquirer_bin]] +[ctp_mastercard.metadata.acquirer_bin] name="acquirer_bin" label="Acquire Bin" placeholder="Enter Acquirer Bin" required=true type="Text" -[[ctp_mastercard.metadata.acquirer_merchant_id]] +[ctp_mastercard.metadata.acquirer_merchant_id] name="acquirer_merchant_id" label="Acquire Merchant Id" placeholder="Enter Acquirer Merchant Id" required=true type="Text" -[[ctp_mastercard.metadata.merchant_category_code]] +[ctp_mastercard.metadata.merchant_category_code] name="merchant_category_code" label="Merchant Category Code" placeholder="Enter Merchant Category Code" required=true type="Text" -[[ctp_mastercard.metadata.merchant_country_code]] +[ctp_mastercard.metadata.merchant_country_code] name="merchant_country_code" label="Merchant Country Code" placeholder="Enter Merchant Country Code" diff --git a/crates/drainer/src/health_check.rs b/crates/drainer/src/health_check.rs index 2ca2c1cc79c..aaf455663f5 100644 --- a/crates/drainer/src/health_check.rs +++ b/crates/drainer/src/health_check.rs @@ -165,21 +165,21 @@ impl HealthCheckInterface for Store { let redis_conn = self.redis_conn.clone(); redis_conn - .serialize_and_set_key_with_expiry("test_key", "test_value", 30) + .serialize_and_set_key_with_expiry(&"test_key".into(), "test_value", 30) .await .change_context(HealthCheckRedisError::SetFailed)?; logger::debug!("Redis set_key was successful"); redis_conn - .get_key::<()>("test_key") + .get_key::<()>(&"test_key".into()) .await .change_context(HealthCheckRedisError::GetFailed)?; logger::debug!("Redis get_key was successful"); redis_conn - .delete_key("test_key") + .delete_key(&"test_key".into()) .await .change_context(HealthCheckRedisError::DeleteFailed)?; @@ -187,7 +187,7 @@ impl HealthCheckInterface for Store { redis_conn .stream_append_entry( - TEST_STREAM_NAME, + &TEST_STREAM_NAME.into(), &redis_interface::RedisEntryId::AutoGeneratedID, TEST_STREAM_DATA.to_vec(), ) @@ -216,7 +216,7 @@ impl HealthCheckInterface for Store { redis_conn .stream_trim_entries( - TEST_STREAM_NAME, + &TEST_STREAM_NAME.into(), ( redis_interface::StreamCapKind::MinID, redis_interface::StreamCapTrim::Exact, diff --git a/crates/drainer/src/stream.rs b/crates/drainer/src/stream.rs index f5b41c53672..9e092b038e8 100644 --- a/crates/drainer/src/stream.rs +++ b/crates/drainer/src/stream.rs @@ -31,7 +31,7 @@ impl Store { match self .redis_conn - .set_key_if_not_exists_with_expiry(stream_key_flag.as_str(), true, None) + .set_key_if_not_exists_with_expiry(&stream_key_flag.as_str().into(), true, None) .await { Ok(resp) => resp == redis::types::SetnxReply::KeySet, @@ -43,7 +43,7 @@ impl Store { } pub async fn make_stream_available(&self, stream_name_flag: &str) -> errors::DrainerResult<()> { - match self.redis_conn.delete_key(stream_name_flag).await { + match self.redis_conn.delete_key(&stream_name_flag.into()).await { Ok(redis::DelReply::KeyDeleted) => Ok(()), Ok(redis::DelReply::KeyNotDeleted) => { logger::error!("Tried to unlock a stream which is already unlocked"); @@ -87,14 +87,14 @@ impl Store { common_utils::date_time::time_it::, _, _>(|| async { let trim_result = self .redis_conn - .stream_trim_entries(stream_name, (trim_kind, trim_type, trim_id)) + .stream_trim_entries(&stream_name.into(), (trim_kind, trim_type, trim_id)) .await .map_err(errors::DrainerError::from)?; // Since xtrim deletes entries below given id excluding the given id. // Hence, deleting the minimum entry id self.redis_conn - .stream_delete_entries(stream_name, minimum_entry_id) + .stream_delete_entries(&stream_name.into(), minimum_entry_id) .await .map_err(errors::DrainerError::from)?; diff --git a/crates/hyperswitch_connectors/src/connectors.rs b/crates/hyperswitch_connectors/src/connectors.rs index bd646c95eb9..15345c8221f 100644 --- a/crates/hyperswitch_connectors/src/connectors.rs +++ b/crates/hyperswitch_connectors/src/connectors.rs @@ -8,6 +8,7 @@ pub mod bitpay; pub mod bluesnap; pub mod boku; pub mod cashtocode; +pub mod chargebee; pub mod coinbase; pub mod cryptopay; pub mod ctp_mastercard; @@ -59,16 +60,17 @@ pub mod zsl; pub use self::{ airwallex::Airwallex, amazonpay::Amazonpay, bambora::Bambora, bamboraapac::Bamboraapac, bankofamerica::Bankofamerica, billwerk::Billwerk, bitpay::Bitpay, bluesnap::Bluesnap, - boku::Boku, cashtocode::Cashtocode, coinbase::Coinbase, cryptopay::Cryptopay, - ctp_mastercard::CtpMastercard, cybersource::Cybersource, datatrans::Datatrans, - 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, paybox::Paybox, payeezy::Payeezy, payu::Payu, placetopay::Placetopay, - powertranz::Powertranz, prophetpay::Prophetpay, rapyd::Rapyd, razorpay::Razorpay, - redsys::Redsys, shift4::Shift4, square::Square, stax::Stax, taxjar::Taxjar, thunes::Thunes, - tsys::Tsys, unified_authentication_service::UnifiedAuthenticationService, volt::Volt, + boku::Boku, cashtocode::Cashtocode, chargebee::Chargebee, coinbase::Coinbase, + cryptopay::Cryptopay, ctp_mastercard::CtpMastercard, cybersource::Cybersource, + datatrans::Datatrans, 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, paybox::Paybox, payeezy::Payeezy, + payu::Payu, placetopay::Placetopay, powertranz::Powertranz, prophetpay::Prophetpay, + rapyd::Rapyd, razorpay::Razorpay, redsys::Redsys, shift4::Shift4, square::Square, stax::Stax, + taxjar::Taxjar, thunes::Thunes, tsys::Tsys, + unified_authentication_service::UnifiedAuthenticationService, volt::Volt, wellsfargo::Wellsfargo, worldline::Worldline, worldpay::Worldpay, xendit::Xendit, zen::Zen, zsl::Zsl, }; diff --git a/crates/hyperswitch_connectors/src/connectors/chargebee.rs b/crates/hyperswitch_connectors/src/connectors/chargebee.rs new file mode 100644 index 00000000000..40dd137c281 --- /dev/null +++ b/crates/hyperswitch_connectors/src/connectors/chargebee.rs @@ -0,0 +1,568 @@ +pub mod transformers; + +use common_utils::{ + errors::CustomResult, + ext_traits::BytesExt, + request::{Method, Request, RequestBuilder, RequestContent}, + types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector}, +}; +use error_stack::{report, ResultExt}; +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}, + }, + 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, ConnectorSpecifications, + ConnectorValidation, + }, + configs::Connectors, + errors, + events::connector_api_logs::ConnectorEvent, + types::{self, Response}, + webhooks, +}; +use masking::{ExposeInterface, Mask}; +use transformers as chargebee; + +use crate::{constants::headers, types::ResponseRouterData, utils}; + +#[derive(Clone)] +pub struct Chargebee { + amount_converter: &'static (dyn AmountConvertor + Sync), +} + +impl Chargebee { + pub fn new() -> &'static Self { + &Self { + amount_converter: &StringMinorUnitForConnector, + } + } +} + +impl api::Payment for Chargebee {} +impl api::PaymentSession for Chargebee {} +impl api::ConnectorAccessToken for Chargebee {} +impl api::MandateSetup for Chargebee {} +impl api::PaymentAuthorize for Chargebee {} +impl api::PaymentSync for Chargebee {} +impl api::PaymentCapture for Chargebee {} +impl api::PaymentVoid for Chargebee {} +impl api::Refund for Chargebee {} +impl api::RefundExecute for Chargebee {} +impl api::RefundSync for Chargebee {} +impl api::PaymentToken for Chargebee {} + +impl ConnectorIntegration + for Chargebee +{ + // Not Implemented (R) +} + +impl ConnectorCommonExt for Chargebee +where + Self: ConnectorIntegration, +{ + fn build_headers( + &self, + req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + let mut header = vec![( + headers::CONTENT_TYPE.to_string(), + self.get_content_type().to_string().into(), + )]; + let mut api_key = self.get_auth_header(&req.connector_auth_type)?; + header.append(&mut api_key); + Ok(header) + } +} + +impl ConnectorCommon for Chargebee { + fn id(&self) -> &'static str { + "chargebee" + } + + fn get_currency_unit(&self) -> api::CurrencyUnit { + api::CurrencyUnit::Minor + } + + fn common_get_content_type(&self) -> &'static str { + "application/json" + } + + fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { + connectors.chargebee.base_url.as_ref() + } + + fn get_auth_header( + &self, + auth_type: &ConnectorAuthType, + ) -> CustomResult)>, errors::ConnectorError> { + let auth = chargebee::ChargebeeAuthType::try_from(auth_type) + .change_context(errors::ConnectorError::FailedToObtainAuthType)?; + Ok(vec![( + headers::AUTHORIZATION.to_string(), + auth.api_key.expose().into_masked(), + )]) + } + + fn build_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + let response: chargebee::ChargebeeErrorResponse = res + .response + .parse_struct("ChargebeeErrorResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + + Ok(ErrorResponse { + status_code: res.status_code, + code: response.code, + message: response.message, + reason: response.reason, + attempt_status: None, + connector_transaction_id: None, + }) + } +} + +impl ConnectorValidation for Chargebee { + //TODO: implement functions when support enabled +} + +impl ConnectorIntegration for Chargebee { + //TODO: implement sessions flow +} + +impl ConnectorIntegration for Chargebee {} + +impl ConnectorIntegration + for Chargebee +{ +} + +impl ConnectorIntegration for Chargebee { + fn get_headers( + &self, + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &PaymentsAuthorizeRouterData, + _connectors: &Connectors, + ) -> CustomResult { + let amount = utils::convert_amount( + self.amount_converter, + req.request.minor_amount, + req.request.currency, + )?; + + let connector_router_data = chargebee::ChargebeeRouterData::from((amount, req)); + let connector_req = chargebee::ChargebeePaymentsRequest::try_from(&connector_router_data)?; + Ok(RequestContent::Json(Box::new(connector_req))) + } + + fn build_request( + &self, + req: &PaymentsAuthorizeRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + RequestBuilder::new() + .method(Method::Post) + .url(&types::PaymentsAuthorizeType::get_url( + self, req, connectors, + )?) + .attach_default_headers() + .headers(types::PaymentsAuthorizeType::get_headers( + self, req, connectors, + )?) + .set_body(types::PaymentsAuthorizeType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &PaymentsAuthorizeRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: chargebee::ChargebeePaymentsResponse = res + .response + .parse_struct("Chargebee PaymentsAuthorizeResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + RouterData::try_from(ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration for Chargebee { + fn get_headers( + &self, + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &PaymentsSyncRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &PaymentsSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + RequestBuilder::new() + .method(Method::Get) + .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) + .build(), + )) + } + + fn handle_response( + &self, + data: &PaymentsSyncRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: chargebee::ChargebeePaymentsResponse = res + .response + .parse_struct("chargebee PaymentsSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + RouterData::try_from(ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration for Chargebee { + fn get_headers( + &self, + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &PaymentsCaptureRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + _req: &PaymentsCaptureRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) + } + + fn build_request( + &self, + req: &PaymentsCaptureRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + RequestBuilder::new() + .method(Method::Post) + .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::PaymentsCaptureType::get_headers( + self, req, connectors, + )?) + .set_body(types::PaymentsCaptureType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &PaymentsCaptureRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: chargebee::ChargebeePaymentsResponse = res + .response + .parse_struct("Chargebee PaymentsCaptureResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + RouterData::try_from(ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration for Chargebee {} + +impl ConnectorIntegration for Chargebee { + fn get_headers( + &self, + req: &RefundsRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &RefundsRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn get_request_body( + &self, + req: &RefundsRouterData, + _connectors: &Connectors, + ) -> CustomResult { + let refund_amount = utils::convert_amount( + self.amount_converter, + req.request.minor_refund_amount, + req.request.currency, + )?; + + let connector_router_data = chargebee::ChargebeeRouterData::from((refund_amount, req)); + let connector_req = chargebee::ChargebeeRefundRequest::try_from(&connector_router_data)?; + Ok(RequestContent::Json(Box::new(connector_req))) + } + + fn build_request( + &self, + 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( + self, req, connectors, + )?) + .set_body(types::RefundExecuteType::get_request_body( + self, req, connectors, + )?) + .build(); + Ok(Some(request)) + } + + fn handle_response( + &self, + data: &RefundsRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult, errors::ConnectorError> { + let response: chargebee::RefundResponse = res + .response + .parse_struct("chargebee RefundResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + RouterData::try_from(ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +impl ConnectorIntegration for Chargebee { + fn get_headers( + &self, + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &RefundSyncRouterData, + _connectors: &Connectors, + ) -> CustomResult { + Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + } + + fn build_request( + &self, + req: &RefundSyncRouterData, + connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + RequestBuilder::new() + .method(Method::Get) + .url(&types::RefundSyncType::get_url(self, req, connectors)?) + .attach_default_headers() + .headers(types::RefundSyncType::get_headers(self, req, connectors)?) + .set_body(types::RefundSyncType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &RefundSyncRouterData, + event_builder: Option<&mut ConnectorEvent>, + res: Response, + ) -> CustomResult { + let response: chargebee::RefundResponse = res + .response + .parse_struct("chargebee RefundSyncResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + event_builder.map(|i| i.set_response_body(&response)); + router_env::logger::info!(connector_response=?response); + RouterData::try_from(ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + event_builder: Option<&mut ConnectorEvent>, + ) -> CustomResult { + self.build_error_response(res, event_builder) + } +} + +#[async_trait::async_trait] +impl webhooks::IncomingWebhook for Chargebee { + fn get_webhook_object_reference_id( + &self, + _request: &webhooks::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) + } + + fn get_webhook_event_type( + &self, + _request: &webhooks::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult { + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) + } + + fn get_webhook_resource_object( + &self, + _request: &webhooks::IncomingWebhookRequestDetails<'_>, + ) -> CustomResult, errors::ConnectorError> { + Err(report!(errors::ConnectorError::WebhooksNotImplemented)) + } +} + +impl ConnectorSpecifications for Chargebee {} diff --git a/crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs b/crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs new file mode 100644 index 00000000000..f825a17acba --- /dev/null +++ b/crates/hyperswitch_connectors/src/connectors/chargebee/transformers.rs @@ -0,0 +1,228 @@ +use common_enums::enums; +use common_utils::types::StringMinorUnit; +use hyperswitch_domain_models::{ + payment_method_data::PaymentMethodData, + router_data::{ConnectorAuthType, RouterData}, + router_flow_types::refunds::{Execute, RSync}, + router_request_types::ResponseId, + router_response_types::{PaymentsResponseData, RefundsResponseData}, + types::{PaymentsAuthorizeRouterData, RefundsRouterData}, +}; +use hyperswitch_interfaces::errors; +use masking::Secret; +use serde::{Deserialize, Serialize}; + +use crate::{ + types::{RefundsResponseRouterData, ResponseRouterData}, + utils::PaymentsAuthorizeRequestData, +}; + +//TODO: Fill the struct with respective fields +pub struct ChargebeeRouterData { + pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub router_data: T, +} + +impl From<(StringMinorUnit, T)> for ChargebeeRouterData { + fn from((amount, item): (StringMinorUnit, T)) -> Self { + //Todo : use utils to convert the amount to the type of amount that a connector accepts + Self { + amount, + router_data: item, + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, PartialEq)] +pub struct ChargebeePaymentsRequest { + amount: StringMinorUnit, + card: ChargebeeCard, +} + +#[derive(Default, Debug, Serialize, Eq, PartialEq)] +pub struct ChargebeeCard { + number: cards::CardNumber, + expiry_month: Secret, + expiry_year: Secret, + cvc: Secret, + complete: bool, +} + +impl TryFrom<&ChargebeeRouterData<&PaymentsAuthorizeRouterData>> for ChargebeePaymentsRequest { + type Error = error_stack::Report; + fn try_from( + item: &ChargebeeRouterData<&PaymentsAuthorizeRouterData>, + ) -> Result { + match item.router_data.request.payment_method_data.clone() { + PaymentMethodData::Card(req_card) => { + let card = ChargebeeCard { + number: req_card.card_number, + expiry_month: req_card.card_exp_month, + expiry_year: req_card.card_exp_year, + cvc: req_card.card_cvc, + complete: item.router_data.request.is_auto_capture()?, + }; + Ok(Self { + amount: item.amount.clone(), + card, + }) + } + _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()), + } + } +} + +//TODO: Fill the struct with respective fields +// Auth Struct +pub struct ChargebeeAuthType { + pub(super) api_key: Secret, +} + +impl TryFrom<&ConnectorAuthType> for ChargebeeAuthType { + type Error = error_stack::Report; + fn try_from(auth_type: &ConnectorAuthType) -> Result { + match auth_type { + ConnectorAuthType::HeaderKey { api_key } => Ok(Self { + api_key: api_key.to_owned(), + }), + _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + } + } +} +// PaymentsResponse +//TODO: Append the remaining status flags +#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum ChargebeePaymentStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for common_enums::AttemptStatus { + fn from(item: ChargebeePaymentStatus) -> Self { + match item { + ChargebeePaymentStatus::Succeeded => Self::Charged, + ChargebeePaymentStatus::Failed => Self::Failure, + ChargebeePaymentStatus::Processing => Self::Authorizing, + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct ChargebeePaymentsResponse { + status: ChargebeePaymentStatus, + id: String, +} + +impl TryFrom> + for RouterData +{ + type Error = error_stack::Report; + fn try_from( + item: ResponseRouterData, + ) -> Result { + Ok(Self { + status: common_enums::AttemptStatus::from(item.response.status), + response: Ok(PaymentsResponseData::TransactionResponse { + resource_id: ResponseId::ConnectorTransactionId(item.response.id), + redirection_data: Box::new(None), + mandate_reference: Box::new(None), + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: None, + incremental_authorization_allowed: None, + charge_id: None, + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +// REFUND : +// Type definition for RefundRequest +#[derive(Default, Debug, Serialize)] +pub struct ChargebeeRefundRequest { + pub amount: StringMinorUnit, +} + +impl TryFrom<&ChargebeeRouterData<&RefundsRouterData>> for ChargebeeRefundRequest { + type Error = error_stack::Report; + fn try_from(item: &ChargebeeRouterData<&RefundsRouterData>) -> Result { + Ok(Self { + amount: item.amount.to_owned(), + }) + } +} + +// Type definition for Refund Response + +#[allow(dead_code)] +#[derive(Debug, Serialize, Default, Deserialize, Clone)] +pub enum RefundStatus { + Succeeded, + Failed, + #[default] + Processing, +} + +impl From for enums::RefundStatus { + fn from(item: RefundStatus) -> Self { + match item { + RefundStatus::Succeeded => Self::Success, + RefundStatus::Failed => Self::Failure, + RefundStatus::Processing => Self::Pending, + //TODO: Review mapping + } + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct RefundResponse { + id: String, + status: RefundStatus, +} + +impl TryFrom> for RefundsRouterData { + type Error = error_stack::Report; + fn try_from( + item: RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +impl TryFrom> for RefundsRouterData { + type Error = error_stack::Report; + fn try_from( + item: RefundsResponseRouterData, + ) -> Result { + Ok(Self { + response: Ok(RefundsResponseData { + connector_refund_id: item.response.id.to_string(), + refund_status: enums::RefundStatus::from(item.response.status), + }), + ..item.data + }) + } +} + +//TODO: Fill the struct with respective fields +#[derive(Default, Debug, Serialize, Deserialize, PartialEq)] +pub struct ChargebeeErrorResponse { + pub status_code: u16, + pub code: String, + pub message: String, + pub reason: Option, +} diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index cd028e81ef1..6ae507790dd 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -26,7 +26,7 @@ use super::{requests::*, response::*}; use crate::{ types::ResponseRouterData, utils::{ - self, AddressData, CardData, ForeignTryFrom, PaymentsAuthorizeRequestData, + self, AddressData, ApplePay, CardData, ForeignTryFrom, PaymentsAuthorizeRequestData, PaymentsSetupMandateRequestData, RouterData as RouterDataTrait, }, }; @@ -150,7 +150,7 @@ fn fetch_payment_instrument( })), WalletData::ApplePay(data) => Ok(PaymentInstrument::Applepay(WalletPayment { payment_type: PaymentType::Encrypted, - wallet_token: Secret::new(data.payment_data), + wallet_token: data.get_applepay_decoded_payment_data()?, ..WalletPayment::default() })), WalletData::AliPayQr(_) diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs index a2db7ad7b6e..e70aff630e3 100644 --- a/crates/hyperswitch_connectors/src/default_implementations.rs +++ b/crates/hyperswitch_connectors/src/default_implementations.rs @@ -105,6 +105,7 @@ default_imp_for_authorize_session_token!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -178,6 +179,7 @@ default_imp_for_calculate_tax!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -251,6 +253,7 @@ default_imp_for_session_update!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -325,6 +328,7 @@ default_imp_for_post_session_tokens!( connectors::Boku, connectors::Billwerk, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -398,6 +402,7 @@ default_imp_for_complete_authorize!( connectors::Bitpay, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Datatrans, @@ -463,6 +468,7 @@ default_imp_for_incremental_authorization!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Datatrans, @@ -536,6 +542,7 @@ default_imp_for_create_customer!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -608,6 +615,7 @@ default_imp_for_connector_redirect_response!( connectors::Bamboraapac, connectors::Bankofamerica, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -675,6 +683,7 @@ default_imp_for_pre_processing_steps!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Datatrans, @@ -746,6 +755,7 @@ default_imp_for_post_processing_steps!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -821,6 +831,7 @@ default_imp_for_approve!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -896,6 +907,7 @@ default_imp_for_reject!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -971,6 +983,7 @@ default_imp_for_webhook_source_verification!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1047,6 +1060,7 @@ default_imp_for_accept_dispute!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1122,6 +1136,7 @@ default_imp_for_submit_evidence!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1197,6 +1212,7 @@ default_imp_for_defend_dispute!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1281,6 +1297,7 @@ default_imp_for_file_upload!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1349,6 +1366,7 @@ default_imp_for_payouts!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Cryptopay, connectors::Datatrans, connectors::Coinbase, @@ -1424,6 +1442,7 @@ default_imp_for_payouts_create!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1501,6 +1520,7 @@ default_imp_for_payouts_retrieve!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1578,6 +1598,7 @@ default_imp_for_payouts_eligibility!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1655,6 +1676,7 @@ default_imp_for_payouts_fulfill!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Datatrans, @@ -1731,6 +1753,7 @@ default_imp_for_payouts_cancel!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1808,6 +1831,7 @@ default_imp_for_payouts_quote!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1885,6 +1909,7 @@ default_imp_for_payouts_recipient!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -1962,6 +1987,7 @@ default_imp_for_payouts_recipient_account!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2039,6 +2065,7 @@ default_imp_for_frm_sale!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2116,6 +2143,7 @@ default_imp_for_frm_checkout!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2193,6 +2221,7 @@ default_imp_for_frm_transaction!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2270,6 +2299,7 @@ default_imp_for_frm_fulfillment!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2347,6 +2377,7 @@ default_imp_for_frm_record_return!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Cybersource, @@ -2421,6 +2452,7 @@ default_imp_for_revoking_mandates!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::Datatrans, @@ -2494,6 +2526,7 @@ default_imp_for_uas_pre_authentication!( connectors::Bitpay, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -2567,6 +2600,7 @@ default_imp_for_uas_post_authentication!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, diff --git a/crates/hyperswitch_connectors/src/default_implementations_v2.rs b/crates/hyperswitch_connectors/src/default_implementations_v2.rs index 485ff86d728..9f0b319bfa1 100644 --- a/crates/hyperswitch_connectors/src/default_implementations_v2.rs +++ b/crates/hyperswitch_connectors/src/default_implementations_v2.rs @@ -215,6 +215,7 @@ default_imp_for_new_connector_integration_payment!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -291,6 +292,7 @@ default_imp_for_new_connector_integration_refund!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -362,6 +364,7 @@ default_imp_for_new_connector_integration_connector_access_token!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -439,6 +442,7 @@ default_imp_for_new_connector_integration_accept_dispute!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -514,6 +518,7 @@ default_imp_for_new_connector_integration_submit_evidence!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -589,6 +594,7 @@ default_imp_for_new_connector_integration_defend_dispute!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -675,6 +681,7 @@ default_imp_for_new_connector_integration_file_upload!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -753,6 +760,7 @@ default_imp_for_new_connector_integration_payouts_create!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -831,6 +839,7 @@ default_imp_for_new_connector_integration_payouts_eligibility!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -909,6 +918,7 @@ default_imp_for_new_connector_integration_payouts_fulfill!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -987,6 +997,7 @@ default_imp_for_new_connector_integration_payouts_cancel!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1065,6 +1076,7 @@ default_imp_for_new_connector_integration_payouts_quote!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1143,6 +1155,7 @@ default_imp_for_new_connector_integration_payouts_recipient!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1221,6 +1234,7 @@ default_imp_for_new_connector_integration_payouts_sync!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1299,6 +1313,7 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1375,6 +1390,7 @@ default_imp_for_new_connector_integration_webhook_source_verification!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1453,6 +1469,7 @@ default_imp_for_new_connector_integration_frm_sale!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1531,6 +1548,7 @@ default_imp_for_new_connector_integration_frm_checkout!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1609,6 +1627,7 @@ default_imp_for_new_connector_integration_frm_transaction!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1687,6 +1706,7 @@ default_imp_for_new_connector_integration_frm_fulfillment!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1765,6 +1785,7 @@ default_imp_for_new_connector_integration_frm_record_return!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, @@ -1840,6 +1861,7 @@ default_imp_for_new_connector_integration_revoking_mandates!( connectors::Bluesnap, connectors::Boku, connectors::Cashtocode, + connectors::Chargebee, connectors::Coinbase, connectors::Cryptopay, connectors::CtpMastercard, diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs index 2f8594662eb..4598fa5d1b5 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types.rs @@ -489,6 +489,7 @@ pub struct BrowserInformation { pub os_type: Option, pub os_version: Option, pub device_model: Option, + pub accept_language: Option, } #[cfg(feature = "v2")] @@ -508,6 +509,7 @@ impl From for BrowserInformation { os_type: value.os_type, os_version: value.os_version, device_model: value.device_model, + accept_language: value.accept_language, } } } diff --git a/crates/hyperswitch_interfaces/src/configs.rs b/crates/hyperswitch_interfaces/src/configs.rs index 4a3b99636dc..efd41aaa4ac 100644 --- a/crates/hyperswitch_interfaces/src/configs.rs +++ b/crates/hyperswitch_interfaces/src/configs.rs @@ -24,6 +24,7 @@ pub struct Connectors { pub boku: ConnectorParams, pub braintree: ConnectorParams, pub cashtocode: ConnectorParams, + pub chargebee: ConnectorParams, pub checkout: ConnectorParams, pub coinbase: ConnectorParams, pub cryptopay: ConnectorParams, diff --git a/crates/redis_interface/Cargo.toml b/crates/redis_interface/Cargo.toml index f9159564830..87f5721365c 100644 --- a/crates/redis_interface/Cargo.toml +++ b/crates/redis_interface/Cargo.toml @@ -7,6 +7,9 @@ rust-version.workspace = true readme = "README.md" license.workspace = true +[features] +multitenancy_fallback = [] + [dependencies] error-stack = "0.4.1" fred = { version = "7.1.2", features = ["metrics", "partial-tracing", "subscriber-client", "check-unresponsive"] } diff --git a/crates/redis_interface/src/commands.rs b/crates/redis_interface/src/commands.rs index 56e9ab98104..affd2b0faa9 100644 --- a/crates/redis_interface/src/commands.rs +++ b/crates/redis_interface/src/commands.rs @@ -17,8 +17,7 @@ use fred::{ prelude::{LuaInterface, RedisErrorKind}, types::{ Expiration, FromRedis, MultipleIDs, MultipleKeys, MultipleOrderedPairs, MultipleStrings, - MultipleValues, RedisKey, RedisMap, RedisValue, ScanType, Scanner, SetOptions, XCap, - XReadResponse, + MultipleValues, RedisMap, RedisValue, ScanType, Scanner, SetOptions, XCap, XReadResponse, }, }; use futures::StreamExt; @@ -26,7 +25,7 @@ use tracing::instrument; use crate::{ errors, - types::{DelReply, HsetnxReply, MsetnxReply, RedisEntryId, SaddReply, SetnxReply}, + types::{DelReply, HsetnxReply, MsetnxReply, RedisEntryId, RedisKey, SaddReply, SetnxReply}, }; impl super::RedisConnectionPool { @@ -37,15 +36,16 @@ impl super::RedisConnectionPool { format!("{}:{}", self.key_prefix, key) } } + #[instrument(level = "DEBUG", skip(self))] - pub async fn set_key(&self, key: &str, value: V) -> CustomResult<(), errors::RedisError> + pub async fn set_key(&self, key: &RedisKey, value: V) -> CustomResult<(), errors::RedisError> where V: TryInto + Debug + Send + Sync, V::Error: Into + Send + Sync, { self.pool .set( - self.add_prefix(key), + key.tenant_aware_key(self), value, Some(Expiration::EX(self.config.default_ttl.into())), None, @@ -57,7 +57,7 @@ impl super::RedisConnectionPool { pub async fn set_key_without_modifying_ttl( &self, - key: &str, + key: &RedisKey, value: V, ) -> CustomResult<(), errors::RedisError> where @@ -65,7 +65,13 @@ impl super::RedisConnectionPool { V::Error: Into + Send + Sync, { self.pool - .set(key, value, Some(Expiration::KEEPTTL), None, false) + .set( + key.tenant_aware_key(self), + value, + Some(Expiration::KEEPTTL), + None, + false, + ) .await .change_context(errors::RedisError::SetFailed) } @@ -87,7 +93,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_key_if_not_exist( &self, - key: &str, + key: &RedisKey, value: V, ttl: Option, ) -> CustomResult @@ -104,7 +110,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_key( &self, - key: &str, + key: &RedisKey, value: V, ) -> CustomResult<(), errors::RedisError> where @@ -120,7 +126,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_key_without_modifying_ttl( &self, - key: &str, + key: &RedisKey, value: V, ) -> CustomResult<(), errors::RedisError> where @@ -137,7 +143,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_key_with_expiry( &self, - key: &str, + key: &RedisKey, value: V, seconds: i64, ) -> CustomResult<(), errors::RedisError> @@ -150,7 +156,7 @@ impl super::RedisConnectionPool { self.pool .set( - self.add_prefix(key), + key.tenant_aware_key(self), serialized.as_slice(), Some(Expiration::EX(seconds)), None, @@ -161,31 +167,67 @@ impl super::RedisConnectionPool { } #[instrument(level = "DEBUG", skip(self))] - pub async fn get_key(&self, key: &str) -> CustomResult + pub async fn get_key(&self, key: &RedisKey) -> CustomResult where V: FromRedis + Unpin + Send + 'static, { - self.pool - .get(self.add_prefix(key)) + match self + .pool + .get(key.tenant_aware_key(self)) .await .change_context(errors::RedisError::GetFailed) + { + Ok(v) => Ok(v), + Err(_err) => { + #[cfg(not(feature = "multitenancy_fallback"))] + { + Err(_err) + } + + #[cfg(feature = "multitenancy_fallback")] + { + self.pool + .get(key.tenant_unaware_key(self)) + .await + .change_context(errors::RedisError::GetFailed) + } + } + } } #[instrument(level = "DEBUG", skip(self))] - pub async fn exists(&self, key: &str) -> CustomResult + pub async fn exists(&self, key: &RedisKey) -> CustomResult where V: Into + Unpin + Send + 'static, { - self.pool - .exists(self.add_prefix(key)) + match self + .pool + .exists(key.tenant_aware_key(self)) .await .change_context(errors::RedisError::GetFailed) + { + Ok(v) => Ok(v), + Err(_err) => { + #[cfg(not(feature = "multitenancy_fallback"))] + { + Err(_err) + } + + #[cfg(feature = "multitenancy_fallback")] + { + self.pool + .exists(key.tenant_unaware_key(self)) + .await + .change_context(errors::RedisError::GetFailed) + } + } + } } #[instrument(level = "DEBUG", skip(self))] pub async fn get_and_deserialize_key( &self, - key: &str, + key: &RedisKey, type_name: &'static str, ) -> CustomResult where @@ -201,19 +243,37 @@ impl super::RedisConnectionPool { } #[instrument(level = "DEBUG", skip(self))] - pub async fn delete_key(&self, key: &str) -> CustomResult { - self.pool - .del(self.add_prefix(key)) + pub async fn delete_key(&self, key: &RedisKey) -> CustomResult { + match self + .pool + .del(key.tenant_aware_key(self)) .await .change_context(errors::RedisError::DeleteFailed) + { + Ok(v) => Ok(v), + Err(_err) => { + #[cfg(not(feature = "multitenancy_fallback"))] + { + Err(_err) + } + + #[cfg(feature = "multitenancy_fallback")] + { + self.pool + .del(key.tenant_unaware_key(self)) + .await + .change_context(errors::RedisError::DeleteFailed) + } + } + } } #[instrument(level = "DEBUG", skip(self))] pub async fn delete_multiple_keys( &self, - keys: &[String], + keys: &[RedisKey], ) -> CustomResult, errors::RedisError> { - let futures = keys.iter().map(|key| self.pool.del(self.add_prefix(key))); + let futures = keys.iter().map(|key| self.delete_key(key)); let del_result = futures::future::try_join_all(futures) .await @@ -225,7 +285,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_key_with_expiry( &self, - key: &str, + key: &RedisKey, value: V, seconds: i64, ) -> CustomResult<(), errors::RedisError> @@ -235,7 +295,7 @@ impl super::RedisConnectionPool { { self.pool .set( - self.add_prefix(key), + key.tenant_aware_key(self), value, Some(Expiration::EX(seconds)), None, @@ -248,7 +308,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_key_if_not_exists_with_expiry( &self, - key: &str, + key: &RedisKey, value: V, seconds: Option, ) -> CustomResult @@ -258,7 +318,7 @@ impl super::RedisConnectionPool { { self.pool .set( - self.add_prefix(key), + key.tenant_aware_key(self), value, Some(Expiration::EX( seconds.unwrap_or(self.config.default_ttl.into()), @@ -273,11 +333,11 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_expiry( &self, - key: &str, + key: &RedisKey, seconds: i64, ) -> CustomResult<(), errors::RedisError> { self.pool - .expire(self.add_prefix(key), seconds) + .expire(key.tenant_aware_key(self), seconds) .await .change_context(errors::RedisError::SetExpiryFailed) } @@ -285,11 +345,11 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_expire_at( &self, - key: &str, + key: &RedisKey, timestamp: i64, ) -> CustomResult<(), errors::RedisError> { self.pool - .expire_at(self.add_prefix(key), timestamp) + .expire_at(key.tenant_aware_key(self), timestamp) .await .change_context(errors::RedisError::SetExpiryFailed) } @@ -297,7 +357,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_hash_fields( &self, - key: &str, + key: &RedisKey, values: V, ttl: Option, ) -> CustomResult<(), errors::RedisError> @@ -307,7 +367,7 @@ impl super::RedisConnectionPool { { let output: Result<(), _> = self .pool - .hset(self.add_prefix(key), values) + .hset(key.tenant_aware_key(self), values) .await .change_context(errors::RedisError::SetHashFailed); // setting expiry for the key @@ -321,7 +381,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn set_hash_field_if_not_exist( &self, - key: &str, + key: &RedisKey, field: &str, value: V, ttl: Option, @@ -332,7 +392,7 @@ impl super::RedisConnectionPool { { let output: Result = self .pool - .hsetnx(self.add_prefix(key), field, value) + .hsetnx(key.tenant_aware_key(self), field, value) .await .change_context(errors::RedisError::SetHashFieldFailed); @@ -348,7 +408,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_hash_field_if_not_exist( &self, - key: &str, + key: &RedisKey, field: &str, value: V, ttl: Option, @@ -367,7 +427,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn serialize_and_set_multiple_hash_field_if_not_exist( &self, - kv: &[(&str, V)], + kv: &[(&RedisKey, V)], field: &str, ttl: Option, ) -> CustomResult, errors::RedisError> @@ -387,7 +447,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn increment_fields_in_hash( &self, - key: &str, + key: &RedisKey, fields_to_increment: &[(T, i64)], ) -> CustomResult, errors::RedisError> where @@ -397,7 +457,7 @@ impl super::RedisConnectionPool { for (field, increment) in fields_to_increment.iter() { values_after_increment.push( self.pool - .hincrby(self.add_prefix(key), field.to_string(), *increment) + .hincrby(key.tenant_aware_key(self), field.to_string(), *increment) .await .change_context(errors::RedisError::IncrementHashFieldFailed)?, ) @@ -409,14 +469,14 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn hscan( &self, - key: &str, + key: &RedisKey, pattern: &str, count: Option, ) -> CustomResult, errors::RedisError> { Ok(self .pool .next() - .hscan::<&str, &str>(&self.add_prefix(key), pattern, count) + .hscan::<&str, &str>(&key.tenant_aware_key(self), pattern, count) .filter_map(|value| async move { match value { Ok(mut v) => { @@ -440,14 +500,14 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn scan( &self, - pattern: &str, + pattern: &RedisKey, count: Option, scan_type: Option, ) -> CustomResult, errors::RedisError> { Ok(self .pool .next() - .scan(&self.add_prefix(pattern), count, scan_type) + .scan(pattern.tenant_aware_key(self), count, scan_type) .filter_map(|value| async move { match value { Ok(mut v) => { @@ -471,7 +531,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn hscan_and_deserialize( &self, - key: &str, + key: &RedisKey, pattern: &str, count: Option, ) -> CustomResult, errors::RedisError> @@ -491,33 +551,69 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn get_hash_field( &self, - key: &str, + key: &RedisKey, field: &str, ) -> CustomResult where V: FromRedis + Unpin + Send + 'static, { - self.pool - .hget(self.add_prefix(key), field) + match self + .pool + .hget(key.tenant_aware_key(self), field) .await .change_context(errors::RedisError::GetHashFieldFailed) + { + Ok(v) => Ok(v), + Err(_err) => { + #[cfg(feature = "multitenancy_fallback")] + { + self.pool + .hget(key.tenant_unaware_key(self), field) + .await + .change_context(errors::RedisError::GetHashFieldFailed) + } + + #[cfg(not(feature = "multitenancy_fallback"))] + { + Err(_err) + } + } + } } #[instrument(level = "DEBUG", skip(self))] - pub async fn get_hash_fields(&self, key: &str) -> CustomResult + pub async fn get_hash_fields(&self, key: &RedisKey) -> CustomResult where V: FromRedis + Unpin + Send + 'static, { - self.pool - .hgetall(self.add_prefix(key)) + match self + .pool + .hgetall(key.tenant_aware_key(self)) .await .change_context(errors::RedisError::GetHashFieldFailed) + { + Ok(v) => Ok(v), + Err(_err) => { + #[cfg(feature = "multitenancy_fallback")] + { + self.pool + .hgetall(key.tenant_unaware_key(self)) + .await + .change_context(errors::RedisError::GetHashFieldFailed) + } + + #[cfg(not(feature = "multitenancy_fallback"))] + { + Err(_err) + } + } + } } #[instrument(level = "DEBUG", skip(self))] pub async fn get_hash_field_and_deserialize( &self, - key: &str, + key: &RedisKey, field: &str, type_name: &'static str, ) -> CustomResult @@ -538,7 +634,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn sadd( &self, - key: &str, + key: &RedisKey, members: V, ) -> CustomResult where @@ -546,7 +642,7 @@ impl super::RedisConnectionPool { V::Error: Into + Send, { self.pool - .sadd(self.add_prefix(key), members) + .sadd(key.tenant_aware_key(self), members) .await .change_context(errors::RedisError::SetAddMembersFailed) } @@ -554,7 +650,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn stream_append_entry( &self, - stream: &str, + stream: &RedisKey, entry_id: &RedisEntryId, fields: F, ) -> CustomResult<(), errors::RedisError> @@ -563,7 +659,7 @@ impl super::RedisConnectionPool { F::Error: Into + Send + Sync, { self.pool - .xadd(self.add_prefix(stream), false, None, entry_id, fields) + .xadd(stream.tenant_aware_key(self), false, None, entry_id, fields) .await .change_context(errors::RedisError::StreamAppendFailed) } @@ -571,14 +667,14 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn stream_delete_entries( &self, - stream: &str, + stream: &RedisKey, ids: Ids, ) -> CustomResult where Ids: Into + Debug + Send + Sync, { self.pool - .xdel(self.add_prefix(stream), ids) + .xdel(stream.tenant_aware_key(self), ids) .await .change_context(errors::RedisError::StreamDeleteFailed) } @@ -586,7 +682,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn stream_trim_entries( &self, - stream: &str, + stream: &RedisKey, xcap: C, ) -> CustomResult where @@ -594,7 +690,7 @@ impl super::RedisConnectionPool { C::Error: Into + Send + Sync, { self.pool - .xtrim(self.add_prefix(stream), xcap) + .xtrim(stream.tenant_aware_key(self), xcap) .await .change_context(errors::RedisError::StreamTrimFailed) } @@ -602,7 +698,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn stream_acknowledge_entries( &self, - stream: &str, + stream: &RedisKey, group: &str, ids: Ids, ) -> CustomResult @@ -610,15 +706,18 @@ impl super::RedisConnectionPool { Ids: Into + Debug + Send + Sync, { self.pool - .xack(self.add_prefix(stream), group, ids) + .xack(stream.tenant_aware_key(self), group, ids) .await .change_context(errors::RedisError::StreamAcknowledgeFailed) } #[instrument(level = "DEBUG", skip(self))] - pub async fn stream_get_length(&self, stream: &str) -> CustomResult { + pub async fn stream_get_length( + &self, + stream: &RedisKey, + ) -> CustomResult { self.pool - .xlen(self.add_prefix(stream)) + .xlen(stream.tenant_aware_key(self)) .await .change_context(errors::RedisError::GetLengthFailed) } @@ -631,10 +730,10 @@ impl super::RedisConnectionPool { let res = multiple_keys .inner() .iter() - .filter_map(|key| key.as_str()) - .map(|k| self.add_prefix(k)) - .map(RedisKey::from) + .filter_map(|key| key.as_str().map(RedisKey::from)) + .map(|k: RedisKey| k.tenant_aware_key(self)) .collect::>(); + MultipleKeys::from(res) } @@ -710,7 +809,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn append_elements_to_list( &self, - key: &str, + key: &RedisKey, elements: V, ) -> CustomResult<(), errors::RedisError> where @@ -718,7 +817,7 @@ impl super::RedisConnectionPool { V::Error: Into + Send, { self.pool - .rpush(self.add_prefix(key), elements) + .rpush(key.tenant_aware_key(self), elements) .await .change_context(errors::RedisError::AppendElementsToListFailed) } @@ -726,20 +825,20 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn get_list_elements( &self, - key: &str, + key: &RedisKey, start: i64, stop: i64, ) -> CustomResult, errors::RedisError> { self.pool - .lrange(self.add_prefix(key), start, stop) + .lrange(key.tenant_aware_key(self), start, stop) .await .change_context(errors::RedisError::GetListElementsFailed) } #[instrument(level = "DEBUG", skip(self))] - pub async fn get_list_length(&self, key: &str) -> CustomResult { + pub async fn get_list_length(&self, key: &RedisKey) -> CustomResult { self.pool - .llen(self.add_prefix(key)) + .llen(key.tenant_aware_key(self)) .await .change_context(errors::RedisError::GetListLengthFailed) } @@ -747,11 +846,11 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn lpop_list_elements( &self, - key: &str, + key: &RedisKey, count: Option, ) -> CustomResult, errors::RedisError> { self.pool - .lpop(self.add_prefix(key), count) + .lpop(key.tenant_aware_key(self), count) .await .change_context(errors::RedisError::PopListElementsFailed) } @@ -761,7 +860,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn consumer_group_create( &self, - stream: &str, + stream: &RedisKey, group: &str, id: &RedisEntryId, ) -> CustomResult<(), errors::RedisError> { @@ -774,7 +873,7 @@ impl super::RedisConnectionPool { } self.pool - .xgroup_create(self.add_prefix(stream), group, id, true) + .xgroup_create(stream.tenant_aware_key(self), group, id, true) .await .change_context(errors::RedisError::ConsumerGroupCreateFailed) } @@ -782,11 +881,11 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn consumer_group_destroy( &self, - stream: &str, + stream: &RedisKey, group: &str, ) -> CustomResult { self.pool - .xgroup_destroy(self.add_prefix(stream), group) + .xgroup_destroy(stream.tenant_aware_key(self), group) .await .change_context(errors::RedisError::ConsumerGroupDestroyFailed) } @@ -795,12 +894,12 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn consumer_group_delete_consumer( &self, - stream: &str, + stream: &RedisKey, group: &str, consumer: &str, ) -> CustomResult { self.pool - .xgroup_delconsumer(self.add_prefix(stream), group, consumer) + .xgroup_delconsumer(stream.tenant_aware_key(self), group, consumer) .await .change_context(errors::RedisError::ConsumerGroupRemoveConsumerFailed) } @@ -808,12 +907,12 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn consumer_group_set_last_id( &self, - stream: &str, + stream: &RedisKey, group: &str, id: &RedisEntryId, ) -> CustomResult { self.pool - .xgroup_setid(self.add_prefix(stream), group, id) + .xgroup_setid(stream.tenant_aware_key(self), group, id) .await .change_context(errors::RedisError::ConsumerGroupSetIdFailed) } @@ -821,7 +920,7 @@ impl super::RedisConnectionPool { #[instrument(level = "DEBUG", skip(self))] pub async fn consumer_group_set_message_owner( &self, - stream: &str, + stream: &RedisKey, group: &str, consumer: &str, min_idle_time: u64, @@ -833,7 +932,7 @@ impl super::RedisConnectionPool { { self.pool .xclaim( - self.add_prefix(stream), + stream.tenant_aware_key(self), group, consumer, min_idle_time, @@ -888,11 +987,15 @@ mod tests { // Act let result1 = redis_conn - .consumer_group_create("TEST1", "GTEST", &RedisEntryId::AutoGeneratedID) + .consumer_group_create(&"TEST1".into(), "GTEST", &RedisEntryId::AutoGeneratedID) .await; let result2 = redis_conn - .consumer_group_create("TEST3", "GTEST", &RedisEntryId::UndeliveredEntryID) + .consumer_group_create( + &"TEST3".into(), + "GTEST", + &RedisEntryId::UndeliveredEntryID, + ) .await; // Assert Setup @@ -914,10 +1017,10 @@ mod tests { let pool = RedisConnectionPool::new(&RedisSettings::default()) .await .expect("failed to create redis connection pool"); - let _ = pool.set_key("key", "value".to_string()).await; + let _ = pool.set_key(&"key".into(), "value".to_string()).await; // Act - let result = pool.delete_key("key").await; + let result = pool.delete_key(&"key".into()).await; // Assert setup result.is_ok() @@ -938,7 +1041,7 @@ mod tests { .expect("failed to create redis connection pool"); // Act - let result = pool.delete_key("key not exists").await; + let result = pool.delete_key(&"key not exists".into()).await; // Assert Setup result.is_ok() diff --git a/crates/redis_interface/src/types.rs b/crates/redis_interface/src/types.rs index 92429f617d1..848996deb4a 100644 --- a/crates/redis_interface/src/types.rs +++ b/crates/redis_interface/src/types.rs @@ -4,7 +4,7 @@ use common_utils::errors::CustomResult; use fred::types::RedisValue as FredRedisValue; -use crate::errors; +use crate::{errors, RedisConnectionPool}; pub struct RedisValue { inner: FredRedisValue, @@ -293,3 +293,24 @@ impl fred::types::FromRedis for SaddReply { } } } + +#[derive(Debug)] +pub struct RedisKey(String); + +impl RedisKey { + pub fn tenant_aware_key(&self, pool: &RedisConnectionPool) -> String { + pool.add_prefix(&self.0) + } + + pub fn tenant_unaware_key(&self, _pool: &RedisConnectionPool) -> String { + self.0.clone() + } +} + +impl> From for RedisKey { + fn from(value: T) -> Self { + let value = value.as_ref(); + + Self(value.to_string()) + } +} diff --git a/crates/router/src/configs/settings.rs b/crates/router/src/configs/settings.rs index 1e74a7bd723..a6877c9286c 100644 --- a/crates/router/src/configs/settings.rs +++ b/crates/router/src/configs/settings.rs @@ -304,16 +304,11 @@ pub struct PaymentLink { #[derive(Debug, Deserialize, Clone, Default)] #[serde(default)] pub struct ForexApi { - pub local_fetch_retry_count: u64, pub api_key: Secret, pub fallback_api_key: Secret, - /// in ms + /// in s pub call_delay: i64, - /// in ms - pub local_fetch_retry_delay: u64, - /// in ms - pub api_timeout: u64, - /// in ms + /// in s pub redis_lock_timeout: u64, } diff --git a/crates/router/src/connector.rs b/crates/router/src/connector.rs index 0bd9190f11c..c926401107c 100644 --- a/crates/router/src/connector.rs +++ b/crates/router/src/connector.rs @@ -36,8 +36,8 @@ pub use hyperswitch_connectors::connectors::{ airwallex, airwallex::Airwallex, amazonpay, amazonpay::Amazonpay, bambora, bambora::Bambora, bamboraapac, bamboraapac::Bamboraapac, bankofamerica, bankofamerica::Bankofamerica, billwerk, billwerk::Billwerk, bitpay, bitpay::Bitpay, bluesnap, bluesnap::Bluesnap, boku, boku::Boku, - cashtocode, cashtocode::Cashtocode, coinbase, coinbase::Coinbase, cryptopay, - cryptopay::Cryptopay, ctp_mastercard, ctp_mastercard::CtpMastercard, cybersource, + cashtocode, cashtocode::Cashtocode, chargebee::Chargebee, coinbase, coinbase::Coinbase, + cryptopay, cryptopay::Cryptopay, ctp_mastercard, ctp_mastercard::CtpMastercard, cybersource, cybersource::Cybersource, datatrans, datatrans::Datatrans, deutschebank, deutschebank::Deutschebank, digitalvirgo, digitalvirgo::Digitalvirgo, dlocal, dlocal::Dlocal, elavon, elavon::Elavon, fiserv, fiserv::Fiserv, fiservemea, fiservemea::Fiservemea, fiuu, diff --git a/crates/router/src/connector/netcetera/netcetera_types.rs b/crates/router/src/connector/netcetera/netcetera_types.rs index a69798314ba..0ecbbf63e3e 100644 --- a/crates/router/src/connector/netcetera/netcetera_types.rs +++ b/crates/router/src/connector/netcetera/netcetera_types.rs @@ -1372,6 +1372,15 @@ pub struct Browser { accept_language: Option>, } +// Split by comma and return the list of accept languages +// If Accept-Language is : fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, List should be [fr-CH, fr, en, de] +pub fn get_list_of_accept_languages(accept_language: String) -> Vec { + accept_language + .split(',') + .map(|lang| lang.split(';').next().unwrap_or(lang).trim().to_string()) + .collect() +} + impl From for Browser { fn from(value: crate::types::BrowserInformation) -> Self { Self { @@ -1388,8 +1397,11 @@ impl From for Browser { browser_user_agent: value.user_agent, challenge_window_size: Some(ChallengeWindowSizeEnum::FullScreen), browser_javascript_enabled: value.java_script_enabled, - // Hardcoding to "en" for now, as there's no accept_language in BrowserInformation - accept_language: Some(vec!["en".to_string()]), + // Default to ["en"] locale if accept_language is not provided + accept_language: value + .accept_language + .map(get_list_of_accept_languages) + .or(Some(vec!["en".to_string()])), } } } diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index 83587609b3f..31c992a7f5a 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -401,6 +401,7 @@ impl TryFrom<&TrustpayRouterData<&types::PaymentsAuthorizeRouterData>> for Trust os_type: None, os_version: None, device_model: None, + accept_language: Some(browser_info.accept_language.unwrap_or("en".to_string())), }; let params = get_mandatory_fields(item.router_data)?; let amount = item.amount.to_owned(); diff --git a/crates/router/src/core/api_locking.rs b/crates/router/src/core/api_locking.rs index 9b45fecee4e..7043a090b2b 100644 --- a/crates/router/src/core/api_locking.rs +++ b/crates/router/src/core/api_locking.rs @@ -79,7 +79,7 @@ impl LockAction { for _retry in 0..lock_retries { let redis_lock_result = redis_conn .set_key_if_not_exists_with_expiry( - redis_locking_key.as_str(), + &redis_locking_key.as_str().into(), state.get_request_id(), Some(i64::from(redis_lock_expiry_seconds)), ) @@ -134,12 +134,15 @@ impl LockAction { let redis_locking_key = input.get_redis_locking_key(merchant_id); match redis_conn - .get_key::>(&redis_locking_key) + .get_key::>(&redis_locking_key.as_str().into()) .await { Ok(val) => { if val == state.get_request_id() { - match redis_conn.delete_key(redis_locking_key.as_str()).await { + match redis_conn + .delete_key(&redis_locking_key.as_str().into()) + .await + { Ok(redis::types::DelReply::KeyDeleted) => { logger::info!("Lock freed for locking input {:?}", input); tracing::Span::current() diff --git a/crates/router/src/core/currency.rs b/crates/router/src/core/currency.rs index 912484b014a..8c1a8512892 100644 --- a/crates/router/src/core/currency.rs +++ b/crates/router/src/core/currency.rs @@ -15,16 +15,11 @@ pub async fn retrieve_forex( ) -> CustomResult, ApiErrorResponse> { let forex_api = state.conf.forex_api.get_inner(); Ok(ApplicationResponse::Json( - get_forex_rates( - &state, - forex_api.call_delay, - forex_api.local_fetch_retry_delay, - forex_api.local_fetch_retry_count, - ) - .await - .change_context(ApiErrorResponse::GenericNotFoundError { - message: "Unable to fetch forex rates".to_string(), - })?, + get_forex_rates(&state, forex_api.call_delay) + .await + .change_context(ApiErrorResponse::GenericNotFoundError { + message: "Unable to fetch forex rates".to_string(), + })?, )) } @@ -53,14 +48,9 @@ pub async fn get_forex_exchange_rates( state: SessionState, ) -> CustomResult { let forex_api = state.conf.forex_api.get_inner(); - let rates = get_forex_rates( - &state, - forex_api.call_delay, - forex_api.local_fetch_retry_delay, - forex_api.local_fetch_retry_count, - ) - .await - .change_context(AnalyticsError::ForexFetchFailed)?; + let rates = get_forex_rates(&state, forex_api.call_delay) + .await + .change_context(AnalyticsError::ForexFetchFailed)?; Ok((*rates.data).clone()) } diff --git a/crates/router/src/core/health_check.rs b/crates/router/src/core/health_check.rs index 31e8cc75f5b..2e5c2956013 100644 --- a/crates/router/src/core/health_check.rs +++ b/crates/router/src/core/health_check.rs @@ -52,21 +52,21 @@ impl HealthCheckInterface for app::SessionState { .change_context(errors::HealthCheckRedisError::RedisConnectionError)?; redis_conn - .serialize_and_set_key_with_expiry("test_key", "test_value", 30) + .serialize_and_set_key_with_expiry(&"test_key".into(), "test_value", 30) .await .change_context(errors::HealthCheckRedisError::SetFailed)?; logger::debug!("Redis set_key was successful"); redis_conn - .get_key::<()>("test_key") + .get_key::<()>(&"test_key".into()) .await .change_context(errors::HealthCheckRedisError::GetFailed)?; logger::debug!("Redis get_key was successful"); redis_conn - .delete_key("test_key") + .delete_key(&"test_key".into()) .await .change_context(errors::HealthCheckRedisError::DeleteFailed)?; diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 5bd2c07073e..7be645a81c7 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -3716,7 +3716,7 @@ pub async fn list_payment_methods( let redis_expiry = state.conf.payment_method_auth.get_inner().redis_expiry; if let Some(rc) = redis_conn { - rc.serialize_and_set_key_with_expiry(pm_auth_key.as_str(), val, redis_expiry) + rc.serialize_and_set_key_with_expiry(&pm_auth_key.as_str().into(), val, redis_expiry) .await .attach_printable("Failed to store pm auth data in redis") .unwrap_or_else(|error| { @@ -5030,7 +5030,7 @@ pub async fn list_customer_payment_method( ); redis_conn - .set_key_with_expiry(&key, pm_metadata.1, intent_fulfillment_time) + .set_key_with_expiry(&key.into(), pm_metadata.1, intent_fulfillment_time) .await .change_context(errors::StorageError::KVError) .change_context(errors::ApiErrorResponse::InternalServerError) diff --git a/crates/router/src/core/payment_methods/vault.rs b/crates/router/src/core/payment_methods/vault.rs index 65ef16cb449..300f1e3054f 100644 --- a/crates/router/src/core/payment_methods/vault.rs +++ b/crates/router/src/core/payment_methods/vault.rs @@ -1043,7 +1043,7 @@ pub async fn create_tokenize( redis_conn .set_key_if_not_exists_with_expiry( - redis_key.as_str(), + &redis_key.as_str().into(), bytes::Bytes::from(encrypted_payload), Some(i64::from(consts::LOCKER_REDIS_EXPIRY_SECONDS)), ) @@ -1089,7 +1089,9 @@ pub async fn get_tokenized_data( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to get redis connection")?; - let response = redis_conn.get_key::(redis_key.as_str()).await; + let response = redis_conn + .get_key::(&redis_key.as_str().into()) + .await; match response { Ok(resp) => { @@ -1150,7 +1152,7 @@ pub async fn delete_tokenized_data( .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to get redis connection")?; - let response = redis_conn.delete_key(redis_key.as_str()).await; + let response = redis_conn.delete_key(&redis_key.as_str().into()).await; match response { Ok(redis_interface::DelReply::KeyDeleted) => Ok(()), diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index fedd23d60ca..e4beaef782c 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -2363,7 +2363,7 @@ impl PaymentRedirectFlow for PaymentAuthenticateCompleteAuthorize { .attach_printable("Failed to get redis connection")?; redis_conn .set_key_with_expiry( - &poll_id, + &poll_id.into(), api_models::poll::PollStatus::Pending.to_string(), crate::consts::POLL_ID_TTL, ) @@ -4231,7 +4231,7 @@ async fn decide_payment_method_tokenize_action( ); let connector_token_option = redis_conn - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to fetch the token from redis")?; @@ -5926,26 +5926,7 @@ where .as_ref() .ok_or(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to find the merchant connector id")?; - if is_network_transaction_id_flow( - state, - is_connector_agnostic_mit_enabled, - connector_data.connector_name, - payment_method_info, - ) { - logger::info!("using network_transaction_id for MIT flow"); - let network_transaction_id = payment_method_info - .network_transaction_id - .as_ref() - .ok_or(errors::ApiErrorResponse::InternalServerError) - .attach_printable("Failed to fetch the network transaction id")?; - - let mandate_reference_id = Some(payments_api::MandateReferenceId::NetworkMandateId( - network_transaction_id.to_string(), - )); - - connector_choice = Some((connector_data, mandate_reference_id.clone())); - break; - } else if connector_mandate_details + if connector_mandate_details .clone() .map(|connector_mandate_details| { connector_mandate_details.contains_key(merchant_connector_id) @@ -5995,6 +5976,25 @@ where break; } } + } else if is_network_transaction_id_flow( + state, + is_connector_agnostic_mit_enabled, + connector_data.connector_name, + payment_method_info, + ) { + logger::info!("using network_transaction_id for MIT flow"); + let network_transaction_id = payment_method_info + .network_transaction_id + .as_ref() + .ok_or(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to fetch the network transaction id")?; + + let mandate_reference_id = Some(payments_api::MandateReferenceId::NetworkMandateId( + network_transaction_id.to_string(), + )); + + connector_choice = Some((connector_data, mandate_reference_id.clone())); + break; } else { continue; } @@ -6832,7 +6832,7 @@ pub async fn get_extended_card_info( let key = helpers::get_redis_key_for_extended_card_info(&merchant_id, &payment_id); let payload = redis_conn - .get_key::(&key) + .get_key::(&key.into()) .await .change_context(errors::ApiErrorResponse::ExtendedCardInfoNotFound)?; 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 28febe8b0b6..03b1ad0340b 100644 --- a/crates/router/src/core/payments/connector_integration_v2_impls.rs +++ b/crates/router/src/core/payments/connector_integration_v2_impls.rs @@ -1041,6 +1041,7 @@ default_imp_for_new_connector_integration_payouts!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Cryptopay, connector::Coinbase, @@ -1578,6 +1579,7 @@ default_imp_for_new_connector_integration_frm!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Cryptopay, connector::Coinbase, @@ -1997,6 +1999,7 @@ default_imp_for_new_connector_integration_connector_authentication!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Cryptopay, connector::Coinbase, diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index 9ce3ad6c020..459d8a50a37 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -431,6 +431,7 @@ default_imp_for_connector_request_id!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Coinbase, connector::Cryptopay, @@ -1521,6 +1522,7 @@ default_imp_for_fraud_check!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Cryptopay, connector::Cybersource, @@ -2110,6 +2112,7 @@ default_imp_for_connector_authentication!( connector::Boku, connector::Braintree, connector::Cashtocode, + connector::Chargebee, connector::Checkout, connector::Cryptopay, connector::Coinbase, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 2e0ecd84df3..760d71726c8 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -2303,7 +2303,7 @@ pub async fn retrieve_payment_token_data( ); let token_data_string = redis_conn - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to fetch the token from redis")? @@ -3795,7 +3795,7 @@ pub async fn insert_merchant_connector_creds_to_config( redis .serialize_and_set_key_with_expiry( - key.as_str(), + &key.as_str().into(), &encoded_data.peek(), consts::CONNECTOR_CREDS_TOKEN_TTL, ) @@ -3911,7 +3911,7 @@ pub async fn get_merchant_connector_account( .attach_printable("Failed to get redis connection") .async_and_then(|redis| async move { redis - .get_and_deserialize_key(key.clone().as_str(), "String") + .get_and_deserialize_key(&key.as_str().into(), "String") .await .change_context( errors::ApiErrorResponse::MerchantConnectorAccountNotFound { @@ -6400,7 +6400,7 @@ pub async fn get_payment_method_details_from_payment_token( .get_required_value("payment_method")?, ); let token_data_string = redis_conn - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to fetch the token from redis")? diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs index a87fab9b17a..da68ee27fd9 100644 --- a/crates/router/src/core/payments/operations/payment_confirm.rs +++ b/crates/router/src/core/payments/operations/payment_confirm.rs @@ -1244,7 +1244,7 @@ impl Domain> for redis_conn .set_key_with_expiry( - &key, + &key.into(), encrypted_payload.clone(), (*merchant_config.ttl_in_secs).into(), ) diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs index 80813ac29b5..13f4de956ec 100644 --- a/crates/router/src/core/payments/types.rs +++ b/crates/router/src/core/payments/types.rs @@ -325,7 +325,11 @@ impl SurchargeMetadata { .get_order_fulfillment_time() .unwrap_or(router_consts::DEFAULT_FULFILLMENT_TIME); redis_conn - .set_hash_fields(&redis_key, value_list, Some(intent_fulfillment_time)) + .set_hash_fields( + &redis_key.as_str().into(), + value_list, + Some(intent_fulfillment_time), + ) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to write to redis")?; @@ -347,7 +351,11 @@ impl SurchargeMetadata { let redis_key = Self::get_surcharge_metadata_redis_key(payment_attempt_id); let value_key = Self::get_surcharge_details_redis_hashset_key(&surcharge_key); let result = redis_conn - .get_hash_field_and_deserialize(&redis_key, &value_key, "SurchargeDetails") + .get_hash_field_and_deserialize( + &redis_key.as_str().into(), + &value_key, + "SurchargeDetails", + ) .await; logger::debug!( "Surcharge result fetched from redis with key = {} and {}", diff --git a/crates/router/src/core/payouts/helpers.rs b/crates/router/src/core/payouts/helpers.rs index 060fc64f891..5ebdea0de67 100644 --- a/crates/router/src/core/payouts/helpers.rs +++ b/crates/router/src/core/payouts/helpers.rs @@ -79,7 +79,7 @@ pub async fn make_payout_method_data( .attach_printable("Failed to get redis connection")?; let hyperswitch_token = redis_conn - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to fetch the token from redis")? diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs index afba73e839c..0577b532cf0 100644 --- a/crates/router/src/core/pm_auth.rs +++ b/crates/router/src/core/pm_auth.rs @@ -63,7 +63,7 @@ pub async fn create_link_token( let pm_auth_key = payload.payment_id.get_pm_auth_key(); redis_conn - .exists::>(&pm_auth_key) + .exists::>(&pm_auth_key.as_str().into()) .await .change_context(ApiErrorResponse::InvalidRequestData { message: "Incorrect payment_id provided in request".to_string(), @@ -77,7 +77,7 @@ pub async fn create_link_token( let pm_auth_configs = redis_conn .get_and_deserialize_key::>( - pm_auth_key.as_str(), + &pm_auth_key.as_str().into(), "Vec", ) .await @@ -772,7 +772,7 @@ async fn get_selected_config_from_redis( let pm_auth_key = payload.payment_id.get_pm_auth_key(); redis_conn - .exists::>(&pm_auth_key) + .exists::>(&pm_auth_key.as_str().into()) .await .change_context(ApiErrorResponse::InvalidRequestData { message: "Incorrect payment_id provided in request".to_string(), @@ -786,7 +786,7 @@ async fn get_selected_config_from_redis( let pm_auth_configs = redis_conn .get_and_deserialize_key::>( - pm_auth_key.as_str(), + &pm_auth_key.as_str().into(), "Vec", ) .await diff --git a/crates/router/src/core/poll.rs b/crates/router/src/core/poll.rs index f0a464be287..dd468a26a70 100644 --- a/crates/router/src/core/poll.rs +++ b/crates/router/src/core/poll.rs @@ -23,7 +23,7 @@ pub async fn retrieve_poll_status( // prepend 'poll_{merchant_id}_' to restrict access to only fetching Poll IDs, as this is a freely passed string in the request let poll_id = super::utils::get_poll_id(merchant_account.get_id(), request_poll_id.clone()); let redis_value = redis_conn - .get_key::>(poll_id.as_str()) + .get_key::>(&poll_id.as_str().into()) .await .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable_lazy(|| { diff --git a/crates/router/src/core/webhooks/incoming.rs b/crates/router/src/core/webhooks/incoming.rs index 4c1a5aeb780..71130f247ad 100644 --- a/crates/router/src/core/webhooks/incoming.rs +++ b/crates/router/src/core/webhooks/incoming.rs @@ -1357,7 +1357,7 @@ async fn external_authentication_incoming_webhook_flow( .attach_printable("Failed to get redis connection")?; redis_conn .set_key_without_modifying_ttl( - &poll_id, + &poll_id.into(), api_models::poll::PollStatus::Completed.to_string(), ) .await diff --git a/crates/router/src/db/ephemeral_key.rs b/crates/router/src/db/ephemeral_key.rs index a77995e4e58..b3e33cd777f 100644 --- a/crates/router/src/db/ephemeral_key.rs +++ b/crates/router/src/db/ephemeral_key.rs @@ -103,7 +103,10 @@ mod storage { .get_redis_conn() .map_err(Into::::into)? .serialize_and_set_multiple_hash_field_if_not_exist( - &[(&secret_key, &created_ek), (&id_key, &created_ek)], + &[ + (&secret_key.as_str().into(), &created_ek), + (&id_key.as_str().into(), &created_ek), + ], "ephkey", None, ) @@ -120,12 +123,12 @@ mod storage { let expire_at = expires.assume_utc().unix_timestamp(); self.get_redis_conn() .map_err(Into::::into)? - .set_expire_at(&secret_key, expire_at) + .set_expire_at(&secret_key.into(), expire_at) .await .change_context(errors::StorageError::KVError)?; self.get_redis_conn() .map_err(Into::::into)? - .set_expire_at(&id_key, expire_at) + .set_expire_at(&id_key.into(), expire_at) .await .change_context(errors::StorageError::KVError)?; Ok(created_ek) @@ -161,8 +164,8 @@ mod storage { .map_err(Into::::into)? .serialize_and_set_multiple_hash_field_if_not_exist( &[ - (&secret_key, &created_ephemeral_key), - (&id_key, &created_ephemeral_key), + (&secret_key.as_str().into(), &created_ephemeral_key), + (&id_key.as_str().into(), &created_ephemeral_key), ], "ephkey", None, @@ -180,12 +183,12 @@ mod storage { let expire_at = expires.assume_utc().unix_timestamp(); self.get_redis_conn() .map_err(Into::::into)? - .set_expire_at(&secret_key, expire_at) + .set_expire_at(&secret_key.into(), expire_at) .await .change_context(errors::StorageError::KVError)?; self.get_redis_conn() .map_err(Into::::into)? - .set_expire_at(&id_key, expire_at) + .set_expire_at(&id_key.into(), expire_at) .await .change_context(errors::StorageError::KVError)?; Ok(created_ephemeral_key) @@ -203,7 +206,7 @@ mod storage { let key = format!("epkey_{key}"); self.get_redis_conn() .map_err(Into::::into)? - .get_hash_field_and_deserialize(&key, "ephkey", "EphemeralKey") + .get_hash_field_and_deserialize(&key.into(), "ephkey", "EphemeralKey") .await .change_context(errors::StorageError::KVError) } @@ -217,7 +220,7 @@ mod storage { let key = format!("epkey_{key}"); self.get_redis_conn() .map_err(Into::::into)? - .get_hash_field_and_deserialize(&key, "ephkey", "EphemeralKeyType") + .get_hash_field_and_deserialize(&key.into(), "ephkey", "EphemeralKeyType") .await .change_context(errors::StorageError::KVError) } @@ -231,13 +234,13 @@ mod storage { self.get_redis_conn() .map_err(Into::::into)? - .delete_key(&format!("epkey_{}", &ek.id)) + .delete_key(&format!("epkey_{}", &ek.id).into()) .await .change_context(errors::StorageError::KVError)?; self.get_redis_conn() .map_err(Into::::into)? - .delete_key(&format!("epkey_{}", &ek.secret)) + .delete_key(&format!("epkey_{}", &ek.secret).into()) .await .change_context(errors::StorageError::KVError)?; Ok(ek) @@ -254,7 +257,7 @@ mod storage { self.get_redis_conn() .map_err(Into::::into)? - .delete_key(&redis_id_key) + .delete_key(&redis_id_key.as_str().into()) .await .map_err(|err| match err.current_context() { RedisError::NotFound => { @@ -265,7 +268,7 @@ mod storage { self.get_redis_conn() .map_err(Into::::into)? - .delete_key(&secret_key) + .delete_key(&secret_key.as_str().into()) .await .map_err(|err| match err.current_context() { RedisError::NotFound => { diff --git a/crates/router/src/db/merchant_connector_account.rs b/crates/router/src/db/merchant_connector_account.rs index ba654b4fce3..34b23a833ac 100644 --- a/crates/router/src/db/merchant_connector_account.rs +++ b/crates/router/src/db/merchant_connector_account.rs @@ -59,7 +59,7 @@ impl ConnectorAccessToken for Store { let maybe_token = self .get_redis_conn() .map_err(Into::::into)? - .get_key::>>(&key) + .get_key::>>(&key.into()) .await .change_context(errors::StorageError::KVError) .attach_printable("DB error when getting access token")?; @@ -88,7 +88,7 @@ impl ConnectorAccessToken for Store { .change_context(errors::StorageError::SerializationFailed)?; self.get_redis_conn() .map_err(Into::::into)? - .set_key_with_expiry(&key, serialized_access_token, access_token.expires) + .set_key_with_expiry(&key.into(), serialized_access_token, access_token.expires) .await .change_context(errors::StorageError::KVError) } diff --git a/crates/router/src/routes/dummy_connector/core.rs b/crates/router/src/routes/dummy_connector/core.rs index aadd7dcaa72..cafb6b58bca 100644 --- a/crates/router/src/routes/dummy_connector/core.rs +++ b/crates/router/src/routes/dummy_connector/core.rs @@ -109,7 +109,7 @@ pub async fn payment_complete( .change_context(errors::DummyConnectorErrors::InternalServerError) .attach_printable("Failed to get redis connection")?; - let _ = redis_conn.delete_key(req.attempt_id.as_str()).await; + let _ = redis_conn.delete_key(&req.attempt_id.as_str().into()).await; if let Ok(payment_data) = payment_data { let updated_payment_data = types::DummyConnectorPaymentData { @@ -220,7 +220,7 @@ pub async fn refund_data( .attach_printable("Failed to get redis connection")?; let refund_data = redis_conn .get_and_deserialize_key::( - refund_id.as_str(), + &refund_id.as_str().into(), "DummyConnectorRefundResponse", ) .await diff --git a/crates/router/src/routes/dummy_connector/utils.rs b/crates/router/src/routes/dummy_connector/utils.rs index 6211c3abf80..edbe6d9dddc 100644 --- a/crates/router/src/routes/dummy_connector/utils.rs +++ b/crates/router/src/routes/dummy_connector/utils.rs @@ -38,7 +38,7 @@ pub async fn store_data_in_redis( .attach_printable("Failed to get redis connection")?; redis_conn - .serialize_and_set_key_with_expiry(&key, data, ttl) + .serialize_and_set_key_with_expiry(&key.into(), data, ttl) .await .change_context(errors::DummyConnectorErrors::PaymentStoringError) .attach_printable("Failed to add data in redis")?; @@ -57,7 +57,7 @@ pub async fn get_payment_data_from_payment_id( redis_conn .get_and_deserialize_key::( - payment_id.as_str(), + &payment_id.as_str().into(), "types DummyConnectorPaymentData", ) .await @@ -75,12 +75,12 @@ pub async fn get_payment_data_by_attempt_id( .attach_printable("Failed to get redis connection")?; redis_conn - .get_and_deserialize_key::(attempt_id.as_str(), "String") + .get_and_deserialize_key::(&attempt_id.as_str().into(), "String") .await .async_and_then(|payment_id| async move { redis_conn .get_and_deserialize_key::( - payment_id.as_str(), + &payment_id.as_str().into(), "DummyConnectorPaymentData", ) .await diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs index c8e6303562c..5f9fe729eeb 100644 --- a/crates/router/src/routes/payment_methods.rs +++ b/crates/router/src/routes/payment_methods.rs @@ -980,7 +980,11 @@ impl ParentPaymentMethodToken { .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to get redis connection")?; redis_conn - .serialize_and_set_key_with_expiry(&self.key_for_token, token, fulfillment_time) + .serialize_and_set_key_with_expiry( + &self.key_for_token.as_str().into(), + token, + fulfillment_time, + ) .await .change_context(errors::StorageError::KVError) .change_context(errors::ApiErrorResponse::InternalServerError) @@ -1004,7 +1008,10 @@ impl ParentPaymentMethodToken { .get_redis_conn() .change_context(errors::ApiErrorResponse::InternalServerError) .attach_printable("Failed to get redis connection")?; - match redis_conn.delete_key(&self.key_for_token).await { + match redis_conn + .delete_key(&self.key_for_token.as_str().into()) + .await + { Ok(_) => Ok(()), Err(err) => { { diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index cd8aa1c3c81..16468aef74c 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -602,7 +602,14 @@ pub async fn payments_confirm( return http_not_implemented(); }; - if let Err(err) = helpers::populate_ip_into_browser_info(&req, &mut payload) { + let header_payload = match HeaderPayload::foreign_try_from(req.headers()) { + Ok(headers) => headers, + Err(err) => { + return api::log_and_return_error_response(err); + } + }; + + if let Err(err) = helpers::populate_browser_info(&req, &mut payload, &header_payload) { return api::log_and_return_error_response(err); } @@ -610,12 +617,6 @@ pub async fn payments_confirm( tracing::Span::current().record("payment_id", payment_id.get_string_repr()); payload.payment_id = Some(payment_types::PaymentIdType::PaymentIntentId(payment_id)); payload.confirm = Some(true); - let header_payload = match HeaderPayload::foreign_try_from(req.headers()) { - Ok(headers) => headers, - Err(err) => { - return api::log_and_return_error_response(err); - } - }; let (auth_type, auth_flow) = match auth::check_client_secret_and_get_auth(req.headers(), &payload) { diff --git a/crates/router/src/routes/payments/helpers.rs b/crates/router/src/routes/payments/helpers.rs index 529475a3584..39a836a8385 100644 --- a/crates/router/src/routes/payments/helpers.rs +++ b/crates/router/src/routes/payments/helpers.rs @@ -8,9 +8,10 @@ use crate::{ }; #[cfg(feature = "v1")] -pub fn populate_ip_into_browser_info( +pub fn populate_browser_info( req: &actix_web::HttpRequest, payload: &mut api::PaymentsRequest, + header_payload: &hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult<()> { let mut browser_info: types::BrowserInformation = payload .browser_info @@ -34,6 +35,7 @@ pub fn populate_ip_into_browser_info( os_type: None, os_version: None, device_model: None, + accept_language: None, }); let ip_address = req @@ -59,6 +61,13 @@ pub fn populate_ip_into_browser_info( }) }); + // If the locale is present in the header payload, we will use it as the accept language + if header_payload.locale.is_some() { + browser_info.accept_language = browser_info + .accept_language + .or(header_payload.locale.clone()); + } + if let Some(api::MandateData { customer_acceptance: Some(api::CustomerAcceptance { diff --git a/crates/router/src/services/authentication/blacklist.rs b/crates/router/src/services/authentication/blacklist.rs index da5f87a450e..6be6cc467bf 100644 --- a/crates/router/src/services/authentication/blacklist.rs +++ b/crates/router/src/services/authentication/blacklist.rs @@ -30,7 +30,7 @@ pub async fn insert_user_in_blacklist(state: &SessionState, user_id: &str) -> Us let redis_conn = get_redis_connection(state).change_context(UserErrors::InternalServerError)?; redis_conn .set_key_with_expiry( - user_blacklist_key.as_str(), + &user_blacklist_key.as_str().into(), date_time::now_unix_timestamp(), expiry, ) @@ -46,7 +46,7 @@ pub async fn insert_role_in_blacklist(state: &SessionState, role_id: &str) -> Us let redis_conn = get_redis_connection(state).change_context(UserErrors::InternalServerError)?; redis_conn .set_key_with_expiry( - role_blacklist_key.as_str(), + &role_blacklist_key.as_str().into(), date_time::now_unix_timestamp(), expiry, ) @@ -61,7 +61,7 @@ pub async fn insert_role_in_blacklist(state: &SessionState, role_id: &str) -> Us async fn invalidate_role_cache(state: &SessionState, role_id: &str) -> RouterResult<()> { let redis_conn = get_redis_connection(state)?; redis_conn - .delete_key(authz::get_cache_key_from_role_id(role_id).as_str()) + .delete_key(&authz::get_cache_key_from_role_id(role_id).as_str().into()) .await .map(|_| ()) .change_context(ApiErrorResponse::InternalServerError) @@ -76,7 +76,7 @@ pub async fn check_user_in_blacklist( let token_issued_at = expiry_to_i64(token_expiry - JWT_TOKEN_TIME_IN_SECS)?; let redis_conn = get_redis_connection(state)?; redis_conn - .get_key::>(token.as_str()) + .get_key::>(&token.as_str().into()) .await .change_context(ApiErrorResponse::InternalServerError) .map(|timestamp| timestamp > Some(token_issued_at)) @@ -91,7 +91,7 @@ pub async fn check_role_in_blacklist( let token_issued_at = expiry_to_i64(token_expiry - JWT_TOKEN_TIME_IN_SECS)?; let redis_conn = get_redis_connection(state)?; redis_conn - .get_key::>(token.as_str()) + .get_key::>(&token.as_str().into()) .await .change_context(ApiErrorResponse::InternalServerError) .map(|timestamp| timestamp > Some(token_issued_at)) @@ -104,7 +104,7 @@ pub async fn insert_email_token_in_blacklist(state: &SessionState, token: &str) let expiry = expiry_to_i64(EMAIL_TOKEN_TIME_IN_SECS).change_context(UserErrors::InternalServerError)?; redis_conn - .set_key_with_expiry(blacklist_key.as_str(), true, expiry) + .set_key_with_expiry(&blacklist_key.as_str().into(), true, expiry) .await .change_context(UserErrors::InternalServerError) } @@ -114,7 +114,7 @@ pub async fn check_email_token_in_blacklist(state: &SessionState, token: &str) - let redis_conn = get_redis_connection(state).change_context(UserErrors::InternalServerError)?; let blacklist_key = format!("{}{token}", EMAIL_TOKEN_BLACKLIST_PREFIX); let key_exists = redis_conn - .exists::<()>(blacklist_key.as_str()) + .exists::<()>(&blacklist_key.as_str().into()) .await .change_context(UserErrors::InternalServerError)?; diff --git a/crates/router/src/services/authorization.rs b/crates/router/src/services/authorization.rs index db3483f8164..0e66654b7b9 100644 --- a/crates/router/src/services/authorization.rs +++ b/crates/router/src/services/authorization.rs @@ -64,7 +64,7 @@ where let redis_conn = get_redis_connection(state)?; redis_conn - .get_and_deserialize_key(&get_cache_key_from_role_id(role_id), "RoleInfo") + .get_and_deserialize_key(&get_cache_key_from_role_id(role_id).into(), "RoleInfo") .await .change_context(ApiErrorResponse::InternalServerError) } @@ -103,7 +103,11 @@ where let redis_conn = get_redis_connection(state)?; redis_conn - .serialize_and_set_key_with_expiry(&get_cache_key_from_role_id(role_id), role_info, expiry) + .serialize_and_set_key_with_expiry( + &get_cache_key_from_role_id(role_id).into(), + role_info, + expiry, + ) .await .change_context(ApiErrorResponse::InternalServerError) } diff --git a/crates/router/src/services/openidconnect.rs b/crates/router/src/services/openidconnect.rs index 0c0f86431a1..44f95b42607 100644 --- a/crates/router/src/services/openidconnect.rs +++ b/crates/router/src/services/openidconnect.rs @@ -35,7 +35,7 @@ pub async fn get_authorization_url( // Save csrf & nonce as key value respectively let key = get_oidc_redis_key(csrf_token.secret()); get_redis_connection(&state)? - .set_key_with_expiry(&key, nonce.secret(), consts::user::REDIS_SSO_TTL) + .set_key_with_expiry(&key.into(), nonce.secret(), consts::user::REDIS_SSO_TTL) .await .change_context(UserErrors::InternalServerError) .attach_printable("Failed to save csrf-nonce in redis")?; @@ -142,7 +142,7 @@ async fn get_nonce_from_redis( let redirect_state = redirect_state.clone().expose(); let key = get_oidc_redis_key(&redirect_state); redis_connection - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(UserErrors::InternalServerError) .attach_printable("Error Fetching CSRF from redis")? diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 243b6116e72..114a877d26f 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -359,6 +359,7 @@ impl ConnectorData { Ok(ConnectorEnum::Old(Box::new(connector::Braintree::new()))) } enums::Connector::Cashtocode => { + // enums::Connector::Chargebee => Ok(ConnectorEnum::Old(Box::new(connector::Chargebee))), Ok(ConnectorEnum::Old(Box::new(connector::Cashtocode::new()))) } enums::Connector::Checkout => { diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 06682f596ed..2348fae72ab 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -225,6 +225,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { api_enums::Connector::Boku => Self::Boku, api_enums::Connector::Braintree => Self::Braintree, api_enums::Connector::Cashtocode => Self::Cashtocode, + // api_enums::Connector::Chargebee => Self::Chargebee, api_enums::Connector::Checkout => Self::Checkout, api_enums::Connector::Coinbase => Self::Coinbase, api_enums::Connector::Cryptopay => Self::Cryptopay, diff --git a/crates/router/src/utils/currency.rs b/crates/router/src/utils/currency.rs index 9ab2780da73..4af9f3865f4 100644 --- a/crates/router/src/utils/currency.rs +++ b/crates/router/src/utils/currency.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc, time::Duration}; +use std::{collections::HashMap, ops::Deref, str::FromStr, sync::Arc}; use api_models::enums; use common_utils::{date_time, errors::CustomResult, events::ApiEventMetric, ext_traits::AsyncExt}; @@ -10,7 +10,8 @@ use redis_interface::DelReply; use router_env::{instrument, tracing}; use rust_decimal::Decimal; use strum::IntoEnumIterator; -use tokio::{sync::RwLock, time::sleep}; +use tokio::sync::RwLock; +use tracing_futures::Instrument; use crate::{ logger, @@ -50,10 +51,14 @@ pub enum ForexCacheError { CouldNotAcquireLock, #[error("Provided currency not acceptable")] CurrencyNotAcceptable, + #[error("Forex configuration error: {0}")] + ConfigurationError(String), #[error("Incorrect entries in default Currency response")] DefaultCurrencyParsingError, #[error("Entry not found in cache")] EntryNotFound, + #[error("Forex data unavailable")] + ForexDataUnavailable, #[error("Expiration time invalid")] InvalidLogExpiry, #[error("Error reading local")] @@ -107,44 +112,19 @@ impl FxExchangeRatesCacheEntry { } } -async fn retrieve_forex_from_local() -> Option { +async fn retrieve_forex_from_local_cache() -> Option { FX_EXCHANGE_RATES_CACHE.read().await.clone() } -async fn save_forex_to_local( +async fn save_forex_data_to_local_cache( exchange_rates_cache_entry: FxExchangeRatesCacheEntry, ) -> CustomResult<(), ForexCacheError> { let mut local = FX_EXCHANGE_RATES_CACHE.write().await; *local = Some(exchange_rates_cache_entry); + logger::debug!("forex_log: forex saved in cache"); Ok(()) } -// Alternative handler for handling the case, When no data in local as well as redis -#[allow(dead_code)] -async fn waited_fetch_and_update_caches( - state: &SessionState, - local_fetch_retry_delay: u64, - local_fetch_retry_count: u64, -) -> CustomResult { - for _n in 1..local_fetch_retry_count { - sleep(Duration::from_millis(local_fetch_retry_delay)).await; - //read from redis and update local plus break the loop and return - match retrieve_forex_from_redis(state).await { - Ok(Some(rates)) => { - save_forex_to_local(rates.clone()).await?; - return Ok(rates.clone()); - } - Ok(None) => continue, - Err(error) => { - logger::error!(?error); - continue; - } - } - } - //acquire lock one last time and try to fetch and update local & redis - successive_fetch_and_save_forex(state, None).await -} - impl TryFrom for ExchangeRates { type Error = error_stack::Report; fn try_from(value: DefaultExchangeRates) -> Result { @@ -178,102 +158,108 @@ impl From for CurrencyFactors { pub async fn get_forex_rates( state: &SessionState, call_delay: i64, - local_fetch_retry_delay: u64, - local_fetch_retry_count: u64, ) -> CustomResult { - if let Some(local_rates) = retrieve_forex_from_local().await { + if let Some(local_rates) = retrieve_forex_from_local_cache().await { if local_rates.is_expired(call_delay) { // expired local data - handler_local_expired(state, call_delay, local_rates).await + logger::debug!("forex_log: Forex stored in cache is expired"); + call_forex_api_and_save_data_to_cache_and_redis(state, Some(local_rates)).await } else { // Valid data present in local + logger::debug!("forex_log: forex found in cache"); Ok(local_rates) } } else { // No data in local - handler_local_no_data( - state, - call_delay, - local_fetch_retry_delay, - local_fetch_retry_count, - ) - .await + call_api_if_redis_forex_data_expired(state, call_delay).await } } -async fn handler_local_no_data( +async fn call_api_if_redis_forex_data_expired( state: &SessionState, call_delay: i64, - _local_fetch_retry_delay: u64, - _local_fetch_retry_count: u64, ) -> CustomResult { - match retrieve_forex_from_redis(state).await { - Ok(Some(data)) => fallback_forex_redis_check(state, data, call_delay).await, + match retrieve_forex_data_from_redis(state).await { + Ok(Some(data)) => call_forex_api_if_redis_data_expired(state, data, call_delay).await, Ok(None) => { // No data in local as well as redis - Ok(successive_fetch_and_save_forex(state, None).await?) + call_forex_api_and_save_data_to_cache_and_redis(state, None).await?; + Err(ForexCacheError::ForexDataUnavailable.into()) } Err(error) => { - logger::error!(?error); - Ok(successive_fetch_and_save_forex(state, None).await?) + // Error in deriving forex rates from redis + logger::error!("forex_error: {:?}", error); + call_forex_api_and_save_data_to_cache_and_redis(state, None).await?; + Err(ForexCacheError::ForexDataUnavailable.into()) } } } -async fn successive_fetch_and_save_forex( +async fn call_forex_api_and_save_data_to_cache_and_redis( state: &SessionState, stale_redis_data: Option, ) -> CustomResult { - match acquire_redis_lock(state).await { - Ok(lock_acquired) => { - if !lock_acquired { - return stale_redis_data.ok_or(ForexCacheError::CouldNotAcquireLock.into()); + // spawn a new thread and do the api fetch and write operations on redis. + let forex_api_key = state.conf.forex_api.get_inner().api_key.peek(); + if forex_api_key.is_empty() { + Err(ForexCacheError::ConfigurationError("api_keys not provided".into()).into()) + } else { + let state = state.clone(); + tokio::spawn( + async move { + acquire_redis_lock_and_call_forex_api(&state) + .await + .map_err(|err| { + logger::error!(forex_error=?err); + }) + .ok(); } - let api_rates = fetch_forex_rates(state).await; - match api_rates { - Ok(rates) => successive_save_data_to_redis_local(state, rates).await, - Err(error) => { - // API not able to fetch data call secondary service - logger::error!(?error); - let secondary_api_rates = fallback_fetch_forex_rates(state).await; - match secondary_api_rates { - Ok(rates) => Ok(successive_save_data_to_redis_local(state, rates).await?), - Err(error) => stale_redis_data.ok_or({ - logger::error!(?error); - release_redis_lock(state).await?; - ForexCacheError::ApiUnresponsive.into() - }), + .in_current_span(), + ); + stale_redis_data.ok_or(ForexCacheError::EntryNotFound.into()) + } +} + +async fn acquire_redis_lock_and_call_forex_api( + state: &SessionState, +) -> CustomResult<(), ForexCacheError> { + let lock_acquired = acquire_redis_lock(state).await?; + if !lock_acquired { + Err(ForexCacheError::CouldNotAcquireLock.into()) + } else { + logger::debug!("forex_log: redis lock acquired"); + let api_rates = fetch_forex_rates_from_primary_api(state).await; + match api_rates { + Ok(rates) => save_forex_data_to_cache_and_redis(state, rates).await, + Err(error) => { + logger::error!(forex_error=?error,"primary_forex_error"); + // API not able to fetch data call secondary service + let secondary_api_rates = fetch_forex_rates_from_fallback_api(state).await; + match secondary_api_rates { + Ok(rates) => save_forex_data_to_cache_and_redis(state, rates).await, + Err(error) => { + release_redis_lock(state).await?; + Err(error) } } } } - Err(error) => stale_redis_data.ok_or({ - logger::error!(?error); - ForexCacheError::ApiUnresponsive.into() - }), } } -async fn successive_save_data_to_redis_local( +async fn save_forex_data_to_cache_and_redis( state: &SessionState, forex: FxExchangeRatesCacheEntry, -) -> CustomResult { - Ok(save_forex_to_redis(state, &forex) +) -> CustomResult<(), ForexCacheError> { + save_forex_data_to_redis(state, &forex) .await .async_and_then(|_rates| release_redis_lock(state)) .await - .async_and_then(|_val| save_forex_to_local(forex.clone())) + .async_and_then(|_val| save_forex_data_to_local_cache(forex.clone())) .await - .map_or_else( - |error| { - logger::error!(?error); - forex.clone() - }, - |_| forex.clone(), - )) } -async fn fallback_forex_redis_check( +async fn call_forex_api_if_redis_data_expired( state: &SessionState, redis_data: FxExchangeRatesCacheEntry, call_delay: i64, @@ -282,57 +268,30 @@ async fn fallback_forex_redis_check( Some(redis_forex) => { // Valid data present in redis let exchange_rates = FxExchangeRatesCacheEntry::new(redis_forex.as_ref().clone()); - save_forex_to_local(exchange_rates.clone()).await?; + logger::debug!("forex_log: forex response found in redis"); + save_forex_data_to_local_cache(exchange_rates.clone()).await?; Ok(exchange_rates) } None => { // redis expired - successive_fetch_and_save_forex(state, Some(redis_data)).await - } - } -} - -async fn handler_local_expired( - state: &SessionState, - call_delay: i64, - local_rates: FxExchangeRatesCacheEntry, -) -> CustomResult { - match retrieve_forex_from_redis(state).await { - Ok(redis_data) => { - match is_redis_expired(redis_data.as_ref(), call_delay).await { - Some(redis_forex) => { - // Valid data present in redis - let exchange_rates = - FxExchangeRatesCacheEntry::new(redis_forex.as_ref().clone()); - save_forex_to_local(exchange_rates.clone()).await?; - Ok(exchange_rates) - } - None => { - // Redis is expired going for API request - successive_fetch_and_save_forex(state, Some(local_rates)).await - } - } - } - Err(error) => { - // data not present in redis waited fetch - logger::error!(?error); - successive_fetch_and_save_forex(state, Some(local_rates)).await + call_forex_api_and_save_data_to_cache_and_redis(state, Some(redis_data)).await } } } -async fn fetch_forex_rates( +async fn fetch_forex_rates_from_primary_api( state: &SessionState, ) -> Result> { let forex_api_key = state.conf.forex_api.get_inner().api_key.peek(); + logger::debug!("forex_log: Primary api call for forex fetch"); let forex_url: String = format!("{}{}{}", FOREX_BASE_URL, forex_api_key, FOREX_BASE_CURRENCY); let forex_request = services::RequestBuilder::new() .method(services::Method::Get) .url(&forex_url) .build(); - logger::info!(?forex_request); + logger::info!(primary_forex_request=?forex_request,"forex_log: Primary api call for forex fetch"); let response = state .api_client .send_request( @@ -352,7 +311,7 @@ async fn fetch_forex_rates( "Unable to parse response received from primary api into ForexResponse", )?; - logger::info!("{:?}", forex_response); + logger::info!(primary_forex_response=?forex_response,"forex_log"); let mut conversions: HashMap = HashMap::new(); for enum_curr in enums::Currency::iter() { @@ -361,7 +320,10 @@ async fn fetch_forex_rates( let from_factor = match Decimal::new(1, 0).checked_div(**rate) { Some(rate) => rate, None => { - logger::error!("Rates for {} not received from API", &enum_curr); + logger::error!( + "forex_error: Rates for {} not received from API", + &enum_curr + ); continue; } }; @@ -369,7 +331,10 @@ async fn fetch_forex_rates( conversions.insert(enum_curr, currency_factors); } None => { - logger::error!("Rates for {} not received from API", &enum_curr); + logger::error!( + "forex_error: Rates for {} not received from API", + &enum_curr + ); } }; } @@ -380,7 +345,7 @@ async fn fetch_forex_rates( ))) } -pub async fn fallback_fetch_forex_rates( +pub async fn fetch_forex_rates_from_fallback_api( state: &SessionState, ) -> CustomResult { let fallback_forex_api_key = state.conf.forex_api.get_inner().fallback_api_key.peek(); @@ -392,7 +357,7 @@ pub async fn fallback_fetch_forex_rates( .url(&fallback_forex_url) .build(); - logger::info!(?fallback_forex_request); + logger::info!(fallback_forex_request=?fallback_forex_request,"forex_log: Fallback api call for forex fetch"); let response = state .api_client .send_request( @@ -413,7 +378,8 @@ pub async fn fallback_fetch_forex_rates( "Unable to parse response received from falback api into ForexResponse", )?; - logger::info!("{:?}", fallback_forex_response); + logger::info!(fallback_forex_response=?fallback_forex_response,"forex_log"); + let mut conversions: HashMap = HashMap::new(); for enum_curr in enums::Currency::iter() { match fallback_forex_response.quotes.get( @@ -428,7 +394,10 @@ pub async fn fallback_fetch_forex_rates( let from_factor = match Decimal::new(1, 0).checked_div(**rate) { Some(rate) => rate, None => { - logger::error!("Rates for {} not received from API", &enum_curr); + logger::error!( + "forex_error: Rates for {} not received from API", + &enum_curr + ); continue; } }; @@ -441,7 +410,10 @@ pub async fn fallback_fetch_forex_rates( CurrencyFactors::new(Decimal::new(1, 0), Decimal::new(1, 0)); conversions.insert(enum_curr, currency_factors); } else { - logger::error!("Rates for {} not received from API", &enum_curr); + logger::error!( + "forex_error: Rates for {} not received from API", + &enum_curr + ); } } }; @@ -450,22 +422,23 @@ pub async fn fallback_fetch_forex_rates( let rates = FxExchangeRatesCacheEntry::new(ExchangeRates::new(enums::Currency::USD, conversions)); match acquire_redis_lock(state).await { - Ok(_) => Ok(successive_save_data_to_redis_local(state, rates).await?), - Err(e) => { - logger::error!(?e); + Ok(_) => { + save_forex_data_to_cache_and_redis(state, rates.clone()).await?; Ok(rates) } + Err(e) => Err(e), } } async fn release_redis_lock( state: &SessionState, ) -> Result> { + logger::debug!("forex_log: Releasing redis lock"); state .store .get_redis_conn() .change_context(ForexCacheError::RedisConnectionError)? - .delete_key(REDIX_FOREX_CACHE_KEY) + .delete_key(&REDIX_FOREX_CACHE_KEY.into()) .await .change_context(ForexCacheError::RedisLockReleaseFailed) .attach_printable("Unable to release redis lock") @@ -473,19 +446,17 @@ async fn release_redis_lock( async fn acquire_redis_lock(state: &SessionState) -> CustomResult { let forex_api = state.conf.forex_api.get_inner(); + logger::debug!("forex_log: Acquiring redis lock"); state .store .get_redis_conn() .change_context(ForexCacheError::RedisConnectionError)? .set_key_if_not_exists_with_expiry( - REDIX_FOREX_CACHE_KEY, + &REDIX_FOREX_CACHE_KEY.into(), "", Some( - i64::try_from( - forex_api.local_fetch_retry_count * forex_api.local_fetch_retry_delay - + forex_api.api_timeout, - ) - .change_context(ForexCacheError::ConversionError)?, + i64::try_from(forex_api.redis_lock_timeout) + .change_context(ForexCacheError::ConversionError)?, ), ) .await @@ -494,28 +465,30 @@ async fn acquire_redis_lock(state: &SessionState) -> CustomResult CustomResult<(), ForexCacheError> { + logger::debug!("forex_log: Saving forex to redis"); app_state .store .get_redis_conn() .change_context(ForexCacheError::RedisConnectionError)? - .serialize_and_set_key(REDIX_FOREX_CACHE_DATA, forex_exchange_cache_entry) + .serialize_and_set_key(&REDIX_FOREX_CACHE_DATA.into(), forex_exchange_cache_entry) .await .change_context(ForexCacheError::RedisWriteError) .attach_printable("Unable to save forex data to redis") } -async fn retrieve_forex_from_redis( +async fn retrieve_forex_data_from_redis( app_state: &SessionState, ) -> CustomResult, ForexCacheError> { + logger::debug!("forex_log: Retrieving forex from redis"); app_state .store .get_redis_conn() .change_context(ForexCacheError::RedisConnectionError)? - .get_and_deserialize_key(REDIX_FOREX_CACHE_DATA, "FxExchangeRatesCache") + .get_and_deserialize_key(&REDIX_FOREX_CACHE_DATA.into(), "FxExchangeRatesCache") .await .change_context(ForexCacheError::EntryNotFound) .attach_printable("Forex entry not found in redis") @@ -529,6 +502,7 @@ async fn is_redis_expired( if cache.timestamp + call_delay > date_time::now_unix_timestamp() { Some(cache.data.clone()) } else { + logger::debug!("forex_log: Forex stored in redis is expired"); None } }) @@ -542,14 +516,9 @@ pub async fn convert_currency( from_currency: String, ) -> CustomResult { let forex_api = state.conf.forex_api.get_inner(); - let rates = get_forex_rates( - &state, - forex_api.call_delay, - forex_api.local_fetch_retry_delay, - forex_api.local_fetch_retry_count, - ) - .await - .change_context(ForexCacheError::ApiError)?; + let rates = get_forex_rates(&state, forex_api.call_delay) + .await + .change_context(ForexCacheError::ApiError)?; let to_currency = enums::Currency::from_str(to_currency.as_str()) .change_context(ForexCacheError::CurrencyNotAcceptable) diff --git a/crates/router/src/utils/user.rs b/crates/router/src/utils/user.rs index ef06531b421..721b0052bda 100644 --- a/crates/router/src/utils/user.rs +++ b/crates/router/src/utils/user.rs @@ -246,7 +246,7 @@ pub async fn set_sso_id_in_redis( let connection = get_redis_connection(state)?; let key = get_oidc_key(&oidc_state.expose()); connection - .set_key_with_expiry(&key, sso_id, REDIS_SSO_TTL) + .set_key_with_expiry(&key.into(), sso_id, REDIS_SSO_TTL) .await .change_context(UserErrors::InternalServerError) .attach_printable("Failed to set sso id in redis") @@ -259,7 +259,7 @@ pub async fn get_sso_id_from_redis( let connection = get_redis_connection(state)?; let key = get_oidc_key(&oidc_state.expose()); connection - .get_key::>(&key) + .get_key::>(&key.into()) .await .change_context(UserErrors::InternalServerError) .attach_printable("Failed to get sso id from redis")? diff --git a/crates/router/src/utils/user/two_factor_auth.rs b/crates/router/src/utils/user/two_factor_auth.rs index 73d692a00e0..b4ced70d735 100644 --- a/crates/router/src/utils/user/two_factor_auth.rs +++ b/crates/router/src/utils/user/two_factor_auth.rs @@ -36,7 +36,7 @@ pub async fn check_totp_in_redis(state: &SessionState, user_id: &str) -> UserRes let redis_conn = super::get_redis_connection(state)?; let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id); redis_conn - .exists::<()>(&key) + .exists::<()>(&key.into()) .await .change_context(UserErrors::InternalServerError) } @@ -45,7 +45,7 @@ pub async fn check_recovery_code_in_redis(state: &SessionState, user_id: &str) - let redis_conn = super::get_redis_connection(state)?; let key = format!("{}{}", consts::user::REDIS_RECOVERY_CODE_PREFIX, user_id); redis_conn - .exists::<()>(&key) + .exists::<()>(&key.into()) .await .change_context(UserErrors::InternalServerError) } @@ -55,7 +55,7 @@ pub async fn insert_totp_in_redis(state: &SessionState, user_id: &str) -> UserRe let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id); redis_conn .set_key_with_expiry( - key.as_str(), + &key.as_str().into(), common_utils::date_time::now_unix_timestamp(), state.conf.user.two_factor_auth_expiry_in_secs, ) @@ -71,7 +71,7 @@ pub async fn insert_totp_secret_in_redis( let redis_conn = super::get_redis_connection(state)?; redis_conn .set_key_with_expiry( - &get_totp_secret_key(user_id), + &get_totp_secret_key(user_id).into(), secret.peek(), consts::user::REDIS_TOTP_SECRET_TTL_IN_SECS, ) @@ -85,7 +85,7 @@ pub async fn get_totp_secret_from_redis( ) -> UserResult>> { let redis_conn = super::get_redis_connection(state)?; redis_conn - .get_key::>(&get_totp_secret_key(user_id)) + .get_key::>(&get_totp_secret_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|secret| secret.map(Into::into)) @@ -94,7 +94,7 @@ pub async fn get_totp_secret_from_redis( pub async fn delete_totp_secret_from_redis(state: &SessionState, user_id: &str) -> UserResult<()> { let redis_conn = super::get_redis_connection(state)?; redis_conn - .delete_key(&get_totp_secret_key(user_id)) + .delete_key(&get_totp_secret_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|_| ()) @@ -109,7 +109,7 @@ pub async fn insert_recovery_code_in_redis(state: &SessionState, user_id: &str) let key = format!("{}{}", consts::user::REDIS_RECOVERY_CODE_PREFIX, user_id); redis_conn .set_key_with_expiry( - key.as_str(), + &key.as_str().into(), common_utils::date_time::now_unix_timestamp(), state.conf.user.two_factor_auth_expiry_in_secs, ) @@ -121,7 +121,7 @@ pub async fn delete_totp_from_redis(state: &SessionState, user_id: &str) -> User let redis_conn = super::get_redis_connection(state)?; let key = format!("{}{}", consts::user::REDIS_TOTP_PREFIX, user_id); redis_conn - .delete_key(&key) + .delete_key(&key.into()) .await .change_context(UserErrors::InternalServerError) .map(|_| ()) @@ -134,7 +134,7 @@ pub async fn delete_recovery_code_from_redis( let redis_conn = super::get_redis_connection(state)?; let key = format!("{}{}", consts::user::REDIS_RECOVERY_CODE_PREFIX, user_id); redis_conn - .delete_key(&key) + .delete_key(&key.into()) .await .change_context(UserErrors::InternalServerError) .map(|_| ()) @@ -159,7 +159,7 @@ pub async fn insert_totp_attempts_in_redis( let redis_conn = super::get_redis_connection(state)?; redis_conn .set_key_with_expiry( - &get_totp_attempts_key(user_id), + &get_totp_attempts_key(user_id).into(), user_totp_attempts, consts::user::REDIS_TOTP_ATTEMPTS_TTL_IN_SECS, ) @@ -169,7 +169,7 @@ pub async fn insert_totp_attempts_in_redis( pub async fn get_totp_attempts_from_redis(state: &SessionState, user_id: &str) -> UserResult { let redis_conn = super::get_redis_connection(state)?; redis_conn - .get_key::>(&get_totp_attempts_key(user_id)) + .get_key::>(&get_totp_attempts_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|v| v.unwrap_or(0)) @@ -183,7 +183,7 @@ pub async fn insert_recovery_code_attempts_in_redis( let redis_conn = super::get_redis_connection(state)?; redis_conn .set_key_with_expiry( - &get_recovery_code_attempts_key(user_id), + &get_recovery_code_attempts_key(user_id).into(), user_recovery_code_attempts, consts::user::REDIS_RECOVERY_CODE_ATTEMPTS_TTL_IN_SECS, ) @@ -197,7 +197,7 @@ pub async fn get_recovery_code_attempts_from_redis( ) -> UserResult { let redis_conn = super::get_redis_connection(state)?; redis_conn - .get_key::>(&get_recovery_code_attempts_key(user_id)) + .get_key::>(&get_recovery_code_attempts_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|v| v.unwrap_or(0)) @@ -209,7 +209,7 @@ pub async fn delete_totp_attempts_from_redis( ) -> UserResult<()> { let redis_conn = super::get_redis_connection(state)?; redis_conn - .delete_key(&get_totp_attempts_key(user_id)) + .delete_key(&get_totp_attempts_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|_| ()) @@ -221,7 +221,7 @@ pub async fn delete_recovery_code_attempts_from_redis( ) -> UserResult<()> { let redis_conn = super::get_redis_connection(state)?; redis_conn - .delete_key(&get_recovery_code_attempts_key(user_id)) + .delete_key(&get_recovery_code_attempts_key(user_id).into()) .await .change_context(UserErrors::InternalServerError) .map(|_| ()) diff --git a/crates/router/tests/cache.rs b/crates/router/tests/cache.rs index a1f85534b6b..7e1fab4bc5a 100644 --- a/crates/router/tests/cache.rs +++ b/crates/router/tests/cache.rs @@ -30,7 +30,7 @@ async fn invalidate_existing_cache_success() { .store .get_redis_conn() .unwrap() - .set_key(&cache_key.clone(), cache_key_value.clone()) + .set_key(&cache_key.clone().into(), cache_key_value.clone()) .await; let api_key = ("api-key", "test_admin"); diff --git a/crates/router/tests/connectors/chargebee.rs b/crates/router/tests/connectors/chargebee.rs new file mode 100644 index 00000000000..33d1c8f18de --- /dev/null +++ b/crates/router/tests/connectors/chargebee.rs @@ -0,0 +1,421 @@ +use hyperswitch_domain_models::payment_method_data::{Card, PaymentMethodData}; +use masking::Secret; +use router::types::{self, api, storage::enums}; +use test_utils::connector_auth; + +use crate::utils::{self, ConnectorActions}; + +#[derive(Clone, Copy)] +struct ChargebeeTest; +impl ConnectorActions for ChargebeeTest {} +impl utils::Connector for ChargebeeTest { + fn get_data(&self) -> api::ConnectorData { + use router::connector::Chargebee; + utils::construct_connector_data_old( + Box::new(Chargebee::new()), + types::Connector::Plaid, + api::GetToken::Connector, + None, + ) + } + + fn get_auth_token(&self) -> types::ConnectorAuthType { + utils::to_connector_auth_type( + connector_auth::ConnectorAuthentication::new() + .chargebee + .expect("Missing connector authentication configuration") + .into(), + ) + } + + fn get_name(&self) -> String { + "chargebee".to_string() + } +} + +static CONNECTOR: ChargebeeTest = ChargebeeTest {}; + +fn get_default_payment_info() -> Option { + None +} + +fn payment_method_details() -> Option { + None +} + +// Cards Positive Tests +// Creates a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_only_authorize_payment() { + let response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized); +} + +// Captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info()) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Partially captures a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_capture_authorized_payment() { + let response = CONNECTOR + .authorize_and_capture_payment( + payment_method_details(), + Some(types::PaymentsCaptureData { + amount_to_capture: 50, + ..utils::PaymentCaptureType::default().0 + }), + get_default_payment_info(), + ) + .await + .expect("Capture payment response"); + assert_eq!(response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_authorized_payment() { + let authorize_response = CONNECTOR + .authorize_payment(payment_method_details(), get_default_payment_info()) + .await + .expect("Authorize payment response"); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Authorized, + Some(types::PaymentsSyncData { + connector_transaction_id: types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("PSync response"); + assert_eq!(response.status, enums::AttemptStatus::Authorized,); +} + +// Voids a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_void_authorized_payment() { + let response = CONNECTOR + .authorize_and_void_payment( + payment_method_details(), + Some(types::PaymentsCancelData { + connector_transaction_id: String::from(""), + cancellation_reason: Some("requested_by_customer".to_string()), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .expect("Void payment response"); + assert_eq!(response.status, enums::AttemptStatus::Voided); +} + +// Refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_manually_captured_payment() { + let response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Synchronizes a refund using the manual capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_manually_captured_refund() { + let refund_response = CONNECTOR + .capture_payment_and_refund( + payment_method_details(), + None, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_make_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); +} + +// Synchronizes a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_auto_captured_payment() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let response = CONNECTOR + .psync_retry_till_status_matches( + enums::AttemptStatus::Charged, + Some(types::PaymentsSyncData { + connector_transaction_id: types::ResponseId::ConnectorTransactionId( + txn_id.unwrap(), + ), + capture_method: Some(enums::CaptureMethod::Automatic), + ..Default::default() + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!(response.status, enums::AttemptStatus::Charged,); +} + +// Refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_auto_captured_payment() { + let response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Partially refunds a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_partially_refund_succeeded_payment() { + let refund_response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + refund_response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_refund_succeeded_payment_multiple_times() { + CONNECTOR + .make_payment_and_multiple_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 50, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await; +} + +// Synchronizes a refund using the automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_sync_refund() { + let refund_response = CONNECTOR + .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) + .await + .unwrap(); + let response = CONNECTOR + .rsync_retry_till_status_matches( + enums::RefundStatus::Success, + refund_response.response.unwrap().connector_refund_id, + None, + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap().refund_status, + enums::RefundStatus::Success, + ); +} + +// Cards Negative scenarios +// Creates a payment with incorrect CVC. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_cvc() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: PaymentMethodData::Card(Card { + card_cvc: Secret::new("12345".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's security code is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry month. +#[actix_web::test] +async fn should_fail_payment_for_invalid_exp_month() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: PaymentMethodData::Card(Card { + card_exp_month: Secret::new("20".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration month is invalid.".to_string(), + ); +} + +// Creates a payment with incorrect expiry year. +#[actix_web::test] +async fn should_fail_payment_for_incorrect_expiry_year() { + let response = CONNECTOR + .make_payment( + Some(types::PaymentsAuthorizeData { + payment_method_data: PaymentMethodData::Card(Card { + card_exp_year: Secret::new("2000".to_string()), + ..utils::CCardType::default().0 + }), + ..utils::PaymentAuthorizeType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Your card's expiration year is invalid.".to_string(), + ); +} + +// Voids a payment using automatic capture flow (Non 3DS). +#[actix_web::test] +async fn should_fail_void_payment_for_auto_capture() { + let authorize_response = CONNECTOR + .make_payment(payment_method_details(), get_default_payment_info()) + .await + .unwrap(); + assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); + let txn_id = utils::get_connector_transaction_id(authorize_response.response); + assert_ne!(txn_id, None, "Empty connector transaction id"); + let void_response = CONNECTOR + .void_payment(txn_id.unwrap(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + void_response.response.unwrap_err().message, + "You cannot cancel this PaymentIntent because it has a status of succeeded." + ); +} + +// Captures a payment using invalid connector payment id. +#[actix_web::test] +async fn should_fail_capture_for_invalid_payment() { + let capture_response = CONNECTOR + .capture_payment("123456789".to_string(), None, get_default_payment_info()) + .await + .unwrap(); + assert_eq!( + capture_response.response.unwrap_err().message, + String::from("No such payment_intent: '123456789'") + ); +} + +// Refunds a payment with refund amount higher than payment amount. +#[actix_web::test] +async fn should_fail_for_refund_amount_higher_than_payment_amount() { + let response = CONNECTOR + .make_payment_and_refund( + payment_method_details(), + Some(types::RefundsData { + refund_amount: 150, + ..utils::PaymentRefundType::default().0 + }), + get_default_payment_info(), + ) + .await + .unwrap(); + assert_eq!( + response.response.unwrap_err().message, + "Refund amount (₹1.50) is greater than charge amount (₹1.00)", + ); +} + +// Connector dependent test cases goes here + +// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests diff --git a/crates/router/tests/connectors/main.rs b/crates/router/tests/connectors/main.rs index 31ceb1a7245..19f0b9f9b2c 100644 --- a/crates/router/tests/connectors/main.rs +++ b/crates/router/tests/connectors/main.rs @@ -22,6 +22,7 @@ mod bitpay; mod bluesnap; mod boku; mod cashtocode; +mod chargebee; mod checkout; mod coinbase; mod cryptopay; diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml index 10db11bb3b0..44c178f3a3b 100644 --- a/crates/router/tests/connectors/sample_auth.toml +++ b/crates/router/tests/connectors/sample_auth.toml @@ -304,4 +304,7 @@ api_key="API Key" api_key="API Key" [unified_authentication_service] -api_key="API Key" \ No newline at end of file +api_key="API Key" + +[chargebee] +api_key= "API Key" \ No newline at end of file diff --git a/crates/router/tests/connectors/trustpay.rs b/crates/router/tests/connectors/trustpay.rs index 2e5ea6d50f1..a5eb08c67e6 100644 --- a/crates/router/tests/connectors/trustpay.rs +++ b/crates/router/tests/connectors/trustpay.rs @@ -52,6 +52,7 @@ fn get_default_browser_info() -> BrowserInformation { os_type: None, os_version: None, device_model: None, + accept_language: Some("en".to_string()), } } diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 2cf3dc965fd..ca818e61753 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -1022,6 +1022,7 @@ impl Default for BrowserInfoType { device_model: Some("Apple IPHONE 7".to_string()), os_type: Some("IOS or ANDROID".to_string()), os_version: Some("IOS 14.5".to_string()), + accept_language: Some("en".to_string()), }; Self(data) } diff --git a/crates/scheduler/src/db/queue.rs b/crates/scheduler/src/db/queue.rs index 748e1f489c2..80f2b8b4c92 100644 --- a/crates/scheduler/src/db/queue.rs +++ b/crates/scheduler/src/db/queue.rs @@ -70,7 +70,7 @@ impl QueueInterface for Store { id: &RedisEntryId, ) -> CustomResult<(), RedisError> { self.get_redis_conn()? - .consumer_group_create(stream, group, id) + .consumer_group_create(&stream.into(), group, id) .await } @@ -83,16 +83,16 @@ impl QueueInterface for Store { ) -> CustomResult { let conn = self.get_redis_conn()?.clone(); let is_lock_acquired = conn - .set_key_if_not_exists_with_expiry(lock_key, lock_val, None) + .set_key_if_not_exists_with_expiry(&lock_key.into(), lock_val, None) .await; Ok(match is_lock_acquired { - Ok(SetnxReply::KeySet) => match conn.set_expiry(lock_key, ttl).await { + Ok(SetnxReply::KeySet) => match conn.set_expiry(&lock_key.into(), ttl).await { Ok(()) => true, #[allow(unused_must_use)] Err(error) => { logger::error!(?error); - conn.delete_key(lock_key).await; + conn.delete_key(&lock_key.into()).await; false } }, @@ -108,7 +108,7 @@ impl QueueInterface for Store { } async fn release_pt_lock(&self, tag: &str, lock_key: &str) -> CustomResult { - let is_lock_released = self.get_redis_conn()?.delete_key(lock_key).await; + let is_lock_released = self.get_redis_conn()?.delete_key(&lock_key.into()).await; Ok(match is_lock_released { Ok(_del_reply) => true, Err(error) => { @@ -125,12 +125,12 @@ impl QueueInterface for Store { fields: Vec<(&str, String)>, ) -> CustomResult<(), RedisError> { self.get_redis_conn()? - .stream_append_entry(stream, entry_id, fields) + .stream_append_entry(&stream.into(), entry_id, fields) .await } async fn get_key(&self, key: &str) -> CustomResult, RedisError> { - self.get_redis_conn()?.get_key::>(key).await + self.get_redis_conn()?.get_key::>(&key.into()).await } } diff --git a/crates/scheduler/src/utils.rs b/crates/scheduler/src/utils.rs index 89328479537..51938e6c14d 100644 --- a/crates/scheduler/src/utils.rs +++ b/crates/scheduler/src/utils.rs @@ -231,13 +231,13 @@ pub async fn get_batches( let batches = batches.into_iter().flatten().collect::>(); let entry_ids = entry_ids.into_iter().flatten().collect::>(); - conn.stream_acknowledge_entries(stream_name, group_name, entry_ids.clone()) + conn.stream_acknowledge_entries(&stream_name.into(), group_name, entry_ids.clone()) .await .map_err(|error| { logger::error!(?error, "Error acknowledging batch in stream"); error.change_context(errors::ProcessTrackerError::BatchUpdateFailed) })?; - conn.stream_delete_entries(stream_name, entry_ids.clone()) + conn.stream_delete_entries(&stream_name.into(), entry_ids.clone()) .await .map_err(|error| { logger::error!(?error, "Error deleting batch from stream"); diff --git a/crates/storage_impl/src/lib.rs b/crates/storage_impl/src/lib.rs index e0722ef52ea..8a329010447 100644 --- a/crates/storage_impl/src/lib.rs +++ b/crates/storage_impl/src/lib.rs @@ -256,7 +256,7 @@ impl KVRouterStore { .cache_store .redis_conn .stream_append_entry( - &stream_name, + &stream_name.into(), &redis_interface::RedisEntryId::AutoGeneratedID, redis_entry .to_field_value_pairs(request_id, global_id) @@ -309,7 +309,7 @@ pub trait UniqueConstraints { let constraints = self.unique_constraints(); let sadd_result = redis_conn .sadd( - &format!("unique_constraint:{}", self.table_name()), + &format!("unique_constraint:{}", self.table_name()).into(), constraints, ) .await?; diff --git a/crates/storage_impl/src/redis/cache.rs b/crates/storage_impl/src/redis/cache.rs index 323d3d6df25..8302b5bf933 100644 --- a/crates/storage_impl/src/redis/cache.rs +++ b/crates/storage_impl/src/redis/cache.rs @@ -299,11 +299,13 @@ where { let type_name = std::any::type_name::(); let key = key.as_ref(); - let redis_val = redis.get_and_deserialize_key::(key, type_name).await; + let redis_val = redis + .get_and_deserialize_key::(&key.into(), type_name) + .await; let get_data_set_redis = || async { let data = fun().await?; redis - .serialize_and_set_key(key, &data) + .serialize_and_set_key(&key.into(), &data) .await .change_context(StorageError::KVError)?; Ok::<_, Report>(data) @@ -380,7 +382,7 @@ pub async fn redact_from_redis_and_publish< let redis_keys_to_be_deleted = keys .clone() .into_iter() - .map(|val| val.get_key_without_prefix().to_owned()) + .map(|val| val.get_key_without_prefix().to_owned().into()) .collect::>(); let del_replies = redis_conn diff --git a/crates/storage_impl/src/redis/kv_store.rs b/crates/storage_impl/src/redis/kv_store.rs index 17974a3b9bc..6e1340abca5 100644 --- a/crates/storage_impl/src/redis/kv_store.rs +++ b/crates/storage_impl/src/redis/kv_store.rs @@ -181,7 +181,7 @@ where logger::debug!(kv_operation= %operation, value = ?value); redis_conn - .set_hash_fields(&key, value, Some(ttl.into())) + .set_hash_fields(&key.into(), value, Some(ttl.into())) .await?; store @@ -193,14 +193,14 @@ where KvOperation::HGet(field) => { let result = redis_conn - .get_hash_field_and_deserialize(&key, field, type_name) + .get_hash_field_and_deserialize(&key.into(), field, type_name) .await?; Ok(KvResult::HGet(result)) } KvOperation::Scan(pattern) => { let result: Vec = redis_conn - .hscan_and_deserialize(&key, pattern, None) + .hscan_and_deserialize(&key.into(), pattern, None) .await .and_then(|result| { if result.is_empty() { @@ -218,7 +218,7 @@ where value.check_for_constraints(&redis_conn).await?; let result = redis_conn - .serialize_and_set_hash_field_if_not_exist(&key, field, value, Some(ttl)) + .serialize_and_set_hash_field_if_not_exist(&key.into(), field, value, Some(ttl)) .await?; if matches!(result, redis_interface::HsetnxReply::KeySet) { @@ -235,7 +235,7 @@ where logger::debug!(kv_operation= %operation, value = ?value); let result = redis_conn - .serialize_and_set_key_if_not_exist(&key, value, Some(ttl.into())) + .serialize_and_set_key_if_not_exist(&key.into(), value, Some(ttl.into())) .await?; value.check_for_constraints(&redis_conn).await?; @@ -251,7 +251,9 @@ where } KvOperation::Get => { - let result = redis_conn.get_and_deserialize_key(&key, type_name).await?; + let result = redis_conn + .get_and_deserialize_key(&key.into(), type_name) + .await?; Ok(KvResult::Get(result)) } } diff --git a/crates/test_utils/src/connector_auth.rs b/crates/test_utils/src/connector_auth.rs index 7b6a1ba6b7a..3b02661c5ce 100644 --- a/crates/test_utils/src/connector_auth.rs +++ b/crates/test_utils/src/connector_auth.rs @@ -27,6 +27,7 @@ pub struct ConnectorAuthentication { pub bluesnap: Option, pub boku: Option, pub cashtocode: Option, + pub chargebee: Option, pub checkout: Option, pub coinbase: Option, pub cryptopay: Option, diff --git a/cypress-tests-v2/package-lock.json b/cypress-tests-v2/package-lock.json index cac88cab055..644b9c9faed 100644 --- a/cypress-tests-v2/package-lock.json +++ b/cypress-tests-v2/package-lock.json @@ -29,9 +29,9 @@ } }, "node_modules/@cypress/request": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.6.tgz", - "integrity": "sha512-fi0eVdCOtKu5Ed6+E8mYxUF6ZTFJDZvHogCBelM0xVXmrDEkyM22gRArQzq1YcHPm1V47Vf/iAD+WgVdUlJCGg==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.7.tgz", + "integrity": "sha512-LzxlLEMbBOPYB85uXrDqvD4MgcenjRBLIns3zyhx7vTPj/0u2eQhzXvPiGcaJrV38Q9dbkExWp6cOHPJ+EtFYg==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -48,7 +48,7 @@ "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "performance-now": "^2.1.0", - "qs": "6.13.0", + "qs": "6.13.1", "safe-buffer": "^5.1.2", "tough-cookie": "^5.0.0", "tunnel-agent": "^0.6.0", @@ -79,6 +79,128 @@ "ms": "^2.1.1" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@types/fs-extra": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", @@ -101,13 +223,13 @@ } }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.20.0" } }, "node_modules/@types/sinonjs__fake-timers": { @@ -118,9 +240,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" }, @@ -460,18 +582,29 @@ "node": ">=6" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -568,9 +701,9 @@ } }, "node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", + "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", "dev": true, "funding": [ { @@ -729,7 +862,7 @@ "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -742,9 +875,9 @@ } }, "node_modules/cypress": { - "version": "13.16.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.16.0.tgz", - "integrity": "sha512-g6XcwqnvzXrqiBQR/5gN+QsyRmKRhls1y5E42fyOvsmU7JuY+wM6uHJWj4ZPttjabzbnRvxcik2WemR8+xT6FA==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.17.0.tgz", + "integrity": "sha512-5xWkaPurwkIljojFidhw8lFScyxhtiFHl/i/3zov+1Z5CmY4t9tjIdvSXfu82Y3w7wt0uR9KkucbhkVvJZLQSA==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -882,9 +1015,9 @@ "license": "MIT" }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { @@ -913,24 +1046,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -951,6 +1066,29 @@ "node": ">=0.3.1" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -994,14 +1132,11 @@ } }, "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, "engines": { "node": ">= 0.4" } @@ -1016,6 +1151,19 @@ "node": ">= 0.4" } }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -1057,7 +1205,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", @@ -1194,6 +1342,38 @@ "flat": "cli.js" } }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1286,17 +1466,22 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.6.tgz", + "integrity": "sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==", "dev": true, "license": "MIT", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -1342,22 +1527,22 @@ } }, "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "peer": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=12" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -1377,6 +1562,23 @@ "node": ">= 6" } }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/global-dirs": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", @@ -1394,13 +1596,13 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1423,36 +1625,10 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -1716,6 +1892,23 @@ "dev": true, "license": "MIT" }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -1973,6 +2166,24 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2037,10 +2248,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "peer": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mocha": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", - "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz", + "integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==", "dev": true, "license": "MIT", "peer": true, @@ -2052,7 +2274,7 @@ "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", - "glob": "^8.1.0", + "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", @@ -2071,7 +2293,7 @@ "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/escape-string-regexp": { @@ -2447,9 +2669,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.8.tgz", - "integrity": "sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", "dev": true, "funding": [ { @@ -2500,9 +2722,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, "license": "MIT", "engines": { @@ -2615,6 +2837,14 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2645,6 +2875,24 @@ "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -2684,9 +2932,9 @@ } }, "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.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "license": "MIT", "bin": { @@ -2753,9 +3001,9 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.13.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", + "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2917,24 +3165,6 @@ "dev": true, "license": "ISC" }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2959,16 +3189,73 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3040,6 +3327,23 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3053,6 +3357,21 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -3128,22 +3447,22 @@ "license": "MIT" }, "node_modules/tldts": { - "version": "6.1.59", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.59.tgz", - "integrity": "sha512-472ilPxsRuqBBpn+KuRBHJvZhk6tTo4yTVsmODrLBNLwRYJPkDfMEHivgNwp5iEl+cbrZzzRtLKRxZs7+QKkRg==", + "version": "6.1.69", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.69.tgz", + "integrity": "sha512-Oh/CqRQ1NXNY7cy9NkTPUauOWiTro0jEYZTioGbOmcQh6EC45oribyIMJp0OJO3677r13tO6SKdWoGZUx2BDFw==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.59" + "tldts-core": "^6.1.69" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.59", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.59.tgz", - "integrity": "sha512-EiYgNf275AQyVORl8HQYYe7rTVnmLb4hkWK7wAk/12Ksy5EiHpmUmTICa4GojookBPC8qkLMBKKwCmzNA47ZPQ==", + "version": "6.1.69", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.69.tgz", + "integrity": "sha512-nygxy9n2PBUFQUtAXAc122gGo+04/j5qr5TGQFZTHafTKYvmARVXt2cA5rgero2/dnXUfkdPtiJoKmrd3T+wdA==", "dev": true, "license": "MIT" }, @@ -3195,9 +3514,9 @@ } }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "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" }, @@ -3235,9 +3554,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "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" }, @@ -3345,6 +3664,26 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/cypress-tests/README.md b/cypress-tests/README.md index 87681bb6ea0..4bcb517d4d2 100644 --- a/cypress-tests/README.md +++ b/cypress-tests/README.md @@ -1,4 +1,4 @@ -# Hyperswitch Cypress Testing Framework +# Hyperswitch Cypress Testing Framework ## Overview @@ -61,7 +61,7 @@ CYPRESS_CONNECTOR="connector_id" npm run cypress:ci ## Getting Started -## Prerequisites +### Prerequisites - Node.js (18.x or above) - npm or yarn @@ -70,7 +70,7 @@ CYPRESS_CONNECTOR="connector_id" npm run cypress:ci > [!NOTE] > To learn about the hardware requirements and software dependencies for running Cypress, refer to the [official documentation](https://docs.cypress.io/app/get-started/install-cypress). -## Installation +### Installation 1. Clone the repository and switch to the project directory: @@ -119,32 +119,33 @@ CYPRESS_CONNECTOR="connector_id" npm run cypress:ci > [!NOTE] > To learn about how `creds` file should be structured, refer to the [example.creds.json](#example-credsjson) section below. -## Running Tests +### Running Tests Execution of Cypress tests can be done in two modes: Development mode (Interactive) and CI mode (Headless). The tests can be executed against a single connector or multiple connectors in parallel. Time taken to execute the tests will vary based on the number of connectors and the number of tests. For a single connector, the tests will take approximately 07-12 minutes to execute (this also depends on the hardware configurations). For Development mode, the tests will run in the Cypress UI where execution of tests can be seen in real-time and provides a larger area for debugging based on the need. In CI mode (Headless), tests run in the terminal without UI interaction and generate reports automatically. -### Development Mode (Interactive) +#### Development Mode (Interactive) ```shell npm run cypress ``` -### CI Mode (Headless) +#### CI Mode (Headless) ```shell # All tests npm run cypress:ci # Specific test suites -npm run cypress:payments # Payment tests +npm run cypress:misc # Miscellaneous tests (e.g. health check, memory cache etc.) npm run cypress:payment-method-list # Payment method list tests +npm run cypress:payments # Payment tests npm run cypress:payouts # Payout tests npm run cypress:routing # Routing tests ``` -### Execute tests against multiple connectors or in parallel +#### Execute tests against multiple connectors or in parallel 1. Set additional environment variables: @@ -178,18 +179,27 @@ The folder structure of this directory is as follows: ```txt . -├── .prettierrc # prettier configs -├── README.md # this file +├── .prettierrc # prettier configs +├── README.md # this file ├── cypress │   ├── e2e -│   │   ├── Test # Directory for test scenarios related to connectors. -│   │   │   ├── 00000-test_<0>.cy.js -│   │   │   ├── ... -│   │   │   └── 0000n-test_.cy.js -│   │   └── Utils # Directory for utility functions related to connectors. -│   │   ├── connector_<1>.js -│   │   ├── ... -│   │   └── connector_.js +│   │   ├── configs # Directory for utility functions related to connectors. +│   │   │   ├── PaymentMethodList +│   │ │   │   ├── connector_<1>.js +│   │   │  │   ├── ... +│   │   │  │   └── connector_.js +│   │   │   ├── Payment +│   │   │   ├── Payout +│   │   │   └── Routing +│   │   └── spec # Directory for test scenarios related to connectors. +│   │   ├── Misc +│   │    │   ├── 00000-test_<0>.cy.js +│   │     │   ├── ... +│   │     │   └── 0000n-test_.cy.js +│   │   ├── Payment +│   │   ├── PaymentMethodList +│   │   ├── Payout +│   │   └── Routing │   ├── fixtures # Directory for storing test data API request. │   │   ├── fixture_<1>.json │   │   ├── ... @@ -197,11 +207,14 @@ The folder structure of this directory is as follows: │   ├── support # Directory for Cypress support files. │   │   ├── commands.js # File containing custom Cypress commands and utilities. │   │   ├── e2e.js -│   │   └── redirectionHandler.js +│   │   └── redirectionHandler.js # Functions for handling redirections in tests │   └── utils -│   ├── RequestBodyUtils.js +│   ├── RequestBodyUtils.js # Utility Functions for handling request bodies │   ├── State.js -│   └── featureFlags.js +│   └── featureFlags.js # Functions for validating and controlling feature flags +├── screenshots +│ └── # Connector directory for storing screenshots of test failures +│ └── .png ├── cypress.config.js # Cypress configuration file. ├── eslint.config.js # linter configuration file. └── package.json # Node.js package file. @@ -240,8 +253,8 @@ To add a new test, create a new test file in the `e2e` directory under respectiv ```javascript // cypress/e2e/Test/NewFeature.cy.js -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; describe("New Feature", () => { let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js b/cypress-tests/cypress/e2e/configs/Payment/Adyen.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Adyen.js rename to cypress-tests/cypress/e2e/configs/Payment/Adyen.js index 95fa82f9675..d5bdd190e95 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Adyen.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Adyen.js @@ -1,4 +1,4 @@ -import { getCustomExchange } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { card_number: "4111111111111111", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js b/cypress-tests/cypress/e2e/configs/Payment/BankOfAmerica.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/BankOfAmerica.js rename to cypress-tests/cypress/e2e/configs/Payment/BankOfAmerica.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js b/cypress-tests/cypress/e2e/configs/Payment/Bluesnap.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Bluesnap.js rename to cypress-tests/cypress/e2e/configs/Payment/Bluesnap.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Checkout.js b/cypress-tests/cypress/e2e/configs/Payment/Checkout.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Checkout.js rename to cypress-tests/cypress/e2e/configs/Payment/Checkout.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js b/cypress-tests/cypress/e2e/configs/Payment/Commons.js similarity index 94% rename from cypress-tests/cypress/e2e/PaymentUtils/Commons.js rename to cypress-tests/cypress/e2e/configs/Payment/Commons.js index 998c6b91f7b..f021a0a98fb 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Commons.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Commons.js @@ -1,45 +1,5 @@ // This file is the default. To override, add to connector.js -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"), -}); - -const connectorName = normalize(globalState.get("connectorId")); - -function normalize(input) { - const exceptions = { - bankofamerica: "Bank of America", - cybersource: "Cybersource", - paybox: "Paybox", - paypal: "Paypal", - wellsfargo: "Wellsfargo", - fiuu: "Fiuu", - noon: "Noon", - // Add more known exceptions here - }; - - if (typeof input !== "string") { - const specName = Cypress.spec.name; - - if (specName.includes("-")) { - const parts = specName.split("-"); - - if (parts.length > 1 && parts[1].includes(".")) { - return parts[1].split(".")[0]; - } - } - - // Fallback - return `${specName}`; - } - - const lowerCaseInput = input.toLowerCase(); - return exceptions[lowerCaseInput] || input; -} +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { card_number: "4111111111111111", @@ -141,68 +101,6 @@ export const fullNameRequiredField = { }; 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. -with `getCustomExchange`, if 501 response is expected, there is no need to pass Response as it considers default values. -*/ - -// Const to get default PaymentExchange object -const getDefaultExchange = () => ({ - Request: {}, - Response: { - status: 501, - body: { - error: { - type: "invalid_request", - message: `Selected payment method through ${connectorName} is not implemented`, - code: "IR_00", - }, - }, - }, -}); - -const getUnsupportedExchange = () => ({ - Request: { - currency: "EUR", - }, - Response: { - status: 400, - body: { - error: { - type: "invalid_request", - message: `Payment method type not supported`, - code: "IR_19", - }, - }, - }, -}); - -// Const to get PaymentExchange with overridden properties -export const getCustomExchange = (overrides) => { - const defaultExchange = getDefaultExchange(); - - return { - ...defaultExchange, - ...(overrides.Configs ? { Configs: overrides.Configs } : {}), - Request: { - ...defaultExchange.Request, - ...(overrides.Request || {}), - }, - Response: { - ...defaultExchange.Response, - ...(overrides.Response || {}), - }, - ...(overrides.ResponseCustom - ? { ResponseCustom: overrides.ResponseCustom } - : {}), - }; -}; - -// Function to update the default status code -export const updateDefaultStatusCode = () => { - return getUnsupportedExchange().Response; -}; export const payment_methods_enabled = [ { diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js b/cypress-tests/cypress/e2e/configs/Payment/Cybersource.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js rename to cypress-tests/cypress/e2e/configs/Payment/Cybersource.js index f918fb2592e..804f9aca0dc 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Cybersource.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Cybersource.js @@ -1,7 +1,5 @@ -import { - connectorDetails as commonConnectorDetails, - getCustomExchange, -} from "./Commons"; +import { connectorDetails as commonConnectorDetails } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { card_number: "4242424242424242", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Datatrans.js b/cypress-tests/cypress/e2e/configs/Payment/Datatrans.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Datatrans.js rename to cypress-tests/cypress/e2e/configs/Payment/Datatrans.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Deutschebank.js b/cypress-tests/cypress/e2e/configs/Payment/Deutschebank.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Deutschebank.js rename to cypress-tests/cypress/e2e/configs/Payment/Deutschebank.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Elavon.js b/cypress-tests/cypress/e2e/configs/Payment/Elavon.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Elavon.js rename to cypress-tests/cypress/e2e/configs/Payment/Elavon.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Fiservemea.js b/cypress-tests/cypress/e2e/configs/Payment/Fiservemea.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Fiservemea.js rename to cypress-tests/cypress/e2e/configs/Payment/Fiservemea.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js b/cypress-tests/cypress/e2e/configs/Payment/Fiuu.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Fiuu.js rename to cypress-tests/cypress/e2e/configs/Payment/Fiuu.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Iatapay.js b/cypress-tests/cypress/e2e/configs/Payment/Iatapay.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Iatapay.js rename to cypress-tests/cypress/e2e/configs/Payment/Iatapay.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/ItauBank.js b/cypress-tests/cypress/e2e/configs/Payment/ItauBank.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/ItauBank.js rename to cypress-tests/cypress/e2e/configs/Payment/ItauBank.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Jpmorgan.js b/cypress-tests/cypress/e2e/configs/Payment/Jpmorgan.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Jpmorgan.js rename to cypress-tests/cypress/e2e/configs/Payment/Jpmorgan.js diff --git a/cypress-tests/cypress/e2e/configs/Payment/Modifiers.js b/cypress-tests/cypress/e2e/configs/Payment/Modifiers.js new file mode 100644 index 00000000000..a2fa7642e74 --- /dev/null +++ b/cypress-tests/cypress/e2e/configs/Payment/Modifiers.js @@ -0,0 +1,104 @@ +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"), +}); + +const connectorName = normalize(globalState.get("connectorId")); + +function normalize(input) { + const exceptions = { + bankofamerica: "Bank of America", + cybersource: "Cybersource", + paybox: "Paybox", + paypal: "Paypal", + wellsfargo: "Wellsfargo", + fiuu: "Fiuu", + noon: "Noon", + // Add more known exceptions here + }; + + if (typeof input !== "string") { + const specName = Cypress.spec.name; + + if (specName.includes("-")) { + const parts = specName.split("-"); + + if (parts.length > 1 && parts[1].includes(".")) { + return parts[1].split(".")[0]; + } + } + + // Fallback + return `${specName}`; + } + + const lowerCaseInput = input.toLowerCase(); + return exceptions[lowerCaseInput] || input; +} + +/* +`getDefaultExchange` contains the default Request and Response to be considered if none provided. +`getCustomExchange` takes in 2 optional fields named as Request and Response. +with `getCustomExchange`, if 501 response is expected, there is no need to pass Response as it considers default values. +*/ + +// Const to get default PaymentExchange object +const getDefaultExchange = () => ({ + Request: {}, + Response: { + status: 501, + body: { + error: { + type: "invalid_request", + message: `Selected payment method through ${connectorName} is not implemented`, + code: "IR_00", + }, + }, + }, +}); + +const getUnsupportedExchange = () => ({ + Request: { + currency: "EUR", + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: `Payment method type not supported`, + code: "IR_19", + }, + }, + }, +}); + +// Const to get PaymentExchange with overridden properties +export const getCustomExchange = (overrides) => { + const defaultExchange = getDefaultExchange(); + + return { + ...defaultExchange, + ...(overrides.Configs ? { Configs: overrides.Configs } : {}), + Request: { + ...defaultExchange.Request, + ...(overrides.Request || {}), + }, + Response: { + ...defaultExchange.Response, + ...(overrides.Response || {}), + }, + ...(overrides.ResponseCustom + ? { ResponseCustom: overrides.ResponseCustom } + : {}), + }; +}; + +// Function to update the default status code +export const updateDefaultStatusCode = () => { + return getUnsupportedExchange().Response; +}; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js b/cypress-tests/cypress/e2e/configs/Payment/Nexixpay.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Nexixpay.js rename to cypress-tests/cypress/e2e/configs/Payment/Nexixpay.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Nmi.js b/cypress-tests/cypress/e2e/configs/Payment/Nmi.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Nmi.js rename to cypress-tests/cypress/e2e/configs/Payment/Nmi.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Noon.js b/cypress-tests/cypress/e2e/configs/Payment/Noon.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Noon.js rename to cypress-tests/cypress/e2e/configs/Payment/Noon.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js b/cypress-tests/cypress/e2e/configs/Payment/Novalnet.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Novalnet.js rename to cypress-tests/cypress/e2e/configs/Payment/Novalnet.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Paybox.js b/cypress-tests/cypress/e2e/configs/Payment/Paybox.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Paybox.js rename to cypress-tests/cypress/e2e/configs/Payment/Paybox.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js b/cypress-tests/cypress/e2e/configs/Payment/Paypal.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Paypal.js rename to cypress-tests/cypress/e2e/configs/Payment/Paypal.js index b30e989a2b7..787ad2afabd 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Paypal.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Paypal.js @@ -1,4 +1,4 @@ -import { getCustomExchange } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { card_number: "4012000033330026", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js b/cypress-tests/cypress/e2e/configs/Payment/Stripe.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Stripe.js rename to cypress-tests/cypress/e2e/configs/Payment/Stripe.js index 8d4d94fa563..d4d3c30fe27 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Stripe.js @@ -1,11 +1,11 @@ import { cardRequiredField, connectorDetails as commonConnectorDetails, - getCustomExchange, } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { - card_number: "4242424242424242", + card_number: "378282246310005", card_exp_month: "10", card_exp_year: "50", card_holder_name: "morino", @@ -82,12 +82,12 @@ const payment_method_data_3ds = { const payment_method_data_no3ds = { card: { - last4: "4242", + last4: "0005", card_type: "CREDIT", - card_network: "Visa", - card_issuer: "STRIPE PAYMENTS UK LIMITED", - card_issuing_country: "UNITEDKINGDOM", - card_isin: "424242", + card_network: "AmericanExpress", + card_issuer: "AmericanExpress", + card_issuing_country: "INDIA", + card_isin: "378282", card_extended_bin: null, card_exp_month: "10", card_exp_year: "50", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js b/cypress-tests/cypress/e2e/configs/Payment/Trustpay.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js rename to cypress-tests/cypress/e2e/configs/Payment/Trustpay.js index 6c4db9df329..cfd3332eaba 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Trustpay.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Trustpay.js @@ -1,4 +1,4 @@ -import { getCustomExchange } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const successfulNo3DSCardDetails = { card_number: "4200000000000000", diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js b/cypress-tests/cypress/e2e/configs/Payment/Utils.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/Utils.js rename to cypress-tests/cypress/e2e/configs/Payment/Utils.js index 011383e8871..c35e5950b73 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Utils.js +++ b/cypress-tests/cypress/e2e/configs/Payment/Utils.js @@ -1,4 +1,4 @@ -import { execConfig, validateConfig } from "../../utils/featureFlags.js"; +import { execConfig, validateConfig } from "../../../utils/featureFlags.js"; import { connectorDetails as adyenConnectorDetails } from "./Adyen.js"; import { connectorDetails as bankOfAmericaConnectorDetails } from "./BankOfAmerica.js"; diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js b/cypress-tests/cypress/e2e/configs/Payment/WellsFargo.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/WellsFargo.js rename to cypress-tests/cypress/e2e/configs/Payment/WellsFargo.js diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/configs/Payment/WorldPay.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js rename to cypress-tests/cypress/e2e/configs/Payment/WorldPay.js index a811cac786e..3e13aeba754 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/configs/Payment/WorldPay.js @@ -1,4 +1,4 @@ -import { getCustomExchange } from "./Commons"; +import { getCustomExchange } from "./Modifiers"; const billing = { address: { diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Xendit.js b/cypress-tests/cypress/e2e/configs/Payment/Xendit.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentUtils/Xendit.js rename to cypress-tests/cypress/e2e/configs/Payment/Xendit.js diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js b/cypress-tests/cypress/e2e/configs/PaymentMethodList/Commons.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentMethodListUtils/Commons.js rename to cypress-tests/cypress/e2e/configs/PaymentMethodList/Commons.js diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Connector.js b/cypress-tests/cypress/e2e/configs/PaymentMethodList/Connector.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentMethodListUtils/Connector.js rename to cypress-tests/cypress/e2e/configs/PaymentMethodList/Connector.js diff --git a/cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js b/cypress-tests/cypress/e2e/configs/PaymentMethodList/Utils.js similarity index 100% rename from cypress-tests/cypress/e2e/PaymentMethodListUtils/Utils.js rename to cypress-tests/cypress/e2e/configs/PaymentMethodList/Utils.js diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Adyen.js b/cypress-tests/cypress/e2e/configs/Payout/Adyen.js similarity index 100% rename from cypress-tests/cypress/e2e/PayoutUtils/Adyen.js rename to cypress-tests/cypress/e2e/configs/Payout/Adyen.js diff --git a/cypress-tests/cypress/e2e/PayoutUtils/AdyenPlatform.js b/cypress-tests/cypress/e2e/configs/Payout/AdyenPlatform.js similarity index 100% rename from cypress-tests/cypress/e2e/PayoutUtils/AdyenPlatform.js rename to cypress-tests/cypress/e2e/configs/Payout/AdyenPlatform.js diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Commons.js b/cypress-tests/cypress/e2e/configs/Payout/Commons.js similarity index 62% rename from cypress-tests/cypress/e2e/PayoutUtils/Commons.js rename to cypress-tests/cypress/e2e/configs/Payout/Commons.js index ecd85b05151..749b39cc8dd 100644 --- a/cypress-tests/cypress/e2e/PayoutUtils/Commons.js +++ b/cypress-tests/cypress/e2e/configs/Payout/Commons.js @@ -1,44 +1,5 @@ // This file is the default. To override, add to connector.js -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"), -}); - -const connectorName = normalise(globalState.get("connectorId")); - -function normalise(input) { - const exceptions = { - adyenplatform: "Adyenplatform", - wise: "Wise", - wellsfargo: "Wellsfargo", - // Add more known exceptions here - }; - - if (typeof input !== "string") { - const specName = Cypress.spec.name; - - if (specName.includes("-")) { - const parts = specName.split("-"); - - if (parts.length > 1 && parts[1].includes(".")) { - return parts[1].split(".")[0]; - } - } - - // Fallback - return `${specName}`; - } - - if (exceptions[input.toLowerCase()]) { - return exceptions[input.toLowerCase()]; - } else { - return input; - } -} +import { getCustomExchange } from "./Modifiers"; const card_data = { card_number: "4111111111111111", @@ -71,44 +32,6 @@ const billing = { }, }; -/* -`getDefaultExchange` contains the default Request and Response to be considered if none provided. -`getCustomExchange` takes in 2 optional fields named as Request and Response. -with `getCustomExchange`, if 501 response is expected, there is no need to pass Response as it considers default values. -*/ - -// Const to get default PaymentExchange object -const getDefaultExchange = () => ({ - Request: {}, - Response: { - status: 501, - body: { - error: { - type: "invalid_request", - message: `Selected payment method through ${connectorName} is not implemented`, - code: "IR_00", - }, - }, - }, -}); - -// Const to get PaymentExchange with overridden properties -export const getCustomExchange = (overrides) => { - const defaultExchange = getDefaultExchange(); - - return { - ...defaultExchange, - Request: { - ...defaultExchange.Request, - ...(overrides.Request || {}), - }, - Response: { - ...defaultExchange.Response, - ...(overrides.Response || {}), - }, - }; -}; - export const connectorDetails = { card_pm: { Create: getCustomExchange({ diff --git a/cypress-tests/cypress/e2e/configs/Payout/Modifiers.js b/cypress-tests/cypress/e2e/configs/Payout/Modifiers.js new file mode 100644 index 00000000000..514f7135a63 --- /dev/null +++ b/cypress-tests/cypress/e2e/configs/Payout/Modifiers.js @@ -0,0 +1,78 @@ +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"), +}); + +const connectorName = normalise(globalState.get("connectorId")); + +function normalise(input) { + const exceptions = { + adyenplatform: "Adyenplatform", + wise: "Wise", + wellsfargo: "Wellsfargo", + // Add more known exceptions here + }; + + if (typeof input !== "string") { + const specName = Cypress.spec.name; + + if (specName.includes("-")) { + const parts = specName.split("-"); + + if (parts.length > 1 && parts[1].includes(".")) { + return parts[1].split(".")[0]; + } + } + + // Fallback + return `${specName}`; + } + + if (exceptions[input.toLowerCase()]) { + return exceptions[input.toLowerCase()]; + } else { + return input; + } +} + +/* +`getDefaultExchange` contains the default Request and Response to be considered if none provided. +`getCustomExchange` takes in 2 optional fields named as Request and Response. +with `getCustomExchange`, if 501 response is expected, there is no need to pass Response as it considers default values. +*/ + +// Const to get default PaymentExchange object +const getDefaultExchange = () => ({ + Request: {}, + Response: { + status: 501, + body: { + error: { + type: "invalid_request", + message: `Selected payment method through ${connectorName} is not implemented`, + code: "IR_00", + }, + }, + }, +}); + +// Const to get PaymentExchange with overridden properties +export const getCustomExchange = (overrides) => { + const defaultExchange = getDefaultExchange(); + + return { + ...defaultExchange, + Request: { + ...defaultExchange.Request, + ...(overrides.Request || {}), + }, + Response: { + ...defaultExchange.Response, + ...(overrides.Response || {}), + }, + }; +}; diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Utils.js b/cypress-tests/cypress/e2e/configs/Payout/Utils.js similarity index 97% rename from cypress-tests/cypress/e2e/PayoutUtils/Utils.js rename to cypress-tests/cypress/e2e/configs/Payout/Utils.js index 4cd122782f2..c97e29e644c 100644 --- a/cypress-tests/cypress/e2e/PayoutUtils/Utils.js +++ b/cypress-tests/cypress/e2e/configs/Payout/Utils.js @@ -1,4 +1,4 @@ -import { validateConfig } from "../../utils/featureFlags.js"; +import { validateConfig } from "../../../utils/featureFlags.js"; import { connectorDetails as adyenConnectorDetails } from "./Adyen.js"; import { connectorDetails as adyenPlatformConnectorDetails } from "./AdyenPlatform.js"; diff --git a/cypress-tests/cypress/e2e/PayoutUtils/Wise.js b/cypress-tests/cypress/e2e/configs/Payout/Wise.js similarity index 100% rename from cypress-tests/cypress/e2e/PayoutUtils/Wise.js rename to cypress-tests/cypress/e2e/configs/Payout/Wise.js diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Adyen.js b/cypress-tests/cypress/e2e/configs/Routing/Adyen.js similarity index 100% rename from cypress-tests/cypress/e2e/RoutingUtils/Adyen.js rename to cypress-tests/cypress/e2e/configs/Routing/Adyen.js diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Autoretries.js b/cypress-tests/cypress/e2e/configs/Routing/Autoretries.js similarity index 100% rename from cypress-tests/cypress/e2e/RoutingUtils/Autoretries.js rename to cypress-tests/cypress/e2e/configs/Routing/Autoretries.js diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Commons.js b/cypress-tests/cypress/e2e/configs/Routing/Commons.js similarity index 100% rename from cypress-tests/cypress/e2e/RoutingUtils/Commons.js rename to cypress-tests/cypress/e2e/configs/Routing/Commons.js diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Stripe.js b/cypress-tests/cypress/e2e/configs/Routing/Stripe.js similarity index 99% rename from cypress-tests/cypress/e2e/RoutingUtils/Stripe.js rename to cypress-tests/cypress/e2e/configs/Routing/Stripe.js index 21e885ac137..e00e3d6ccbb 100644 --- a/cypress-tests/cypress/e2e/RoutingUtils/Stripe.js +++ b/cypress-tests/cypress/e2e/configs/Routing/Stripe.js @@ -1,5 +1,3 @@ -import {} from "./Commons"; - const successfulNo3DSCardDetails = { card_number: "4242424242424242", card_exp_month: "10", diff --git a/cypress-tests/cypress/e2e/RoutingUtils/Utils.js b/cypress-tests/cypress/e2e/configs/Routing/Utils.js similarity index 100% rename from cypress-tests/cypress/e2e/RoutingUtils/Utils.js rename to cypress-tests/cypress/e2e/configs/Routing/Utils.js diff --git a/cypress-tests/cypress/e2e/spec/Misc/00000-HealthCheck.cy.js b/cypress-tests/cypress/e2e/spec/Misc/00000-HealthCheck.cy.js new file mode 100644 index 00000000000..d887e43cca8 --- /dev/null +++ b/cypress-tests/cypress/e2e/spec/Misc/00000-HealthCheck.cy.js @@ -0,0 +1,21 @@ +import State from "../../../utils/State"; + +let globalState; + +describe("In Memory Cache configs", () => { + before("seed global state", () => { + cy.task("getGlobalState").then((state) => { + globalState = new State(state); + }); + }); + + after("flush global state", () => { + cy.task("setGlobalState", globalState.data); + }); + + context("Health Check", () => { + it("Create Configs", () => { + cy.healthCheck(globalState); + }); + }); +}); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00028-MemoryCacheConfigs.cy.js b/cypress-tests/cypress/e2e/spec/Misc/00001-MemoryCacheConfigs.cy.js similarity index 58% rename from cypress-tests/cypress/e2e/PaymentTest/00028-MemoryCacheConfigs.cy.js rename to cypress-tests/cypress/e2e/spec/Misc/00001-MemoryCacheConfigs.cy.js index afa7ceda0d1..03b3d8cb89e 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00028-MemoryCacheConfigs.cy.js +++ b/cypress-tests/cypress/e2e/spec/Misc/00001-MemoryCacheConfigs.cy.js @@ -1,8 +1,8 @@ -import State from "../../utils/State"; +import State from "../../../utils/State"; let globalState; -describe("In Memory Cache Test", () => { +describe("In Memory Cache configs", () => { before("seed global state", () => { cy.task("getGlobalState").then((state) => { globalState = new State(state); @@ -19,17 +19,17 @@ describe("In Memory Cache Test", () => { const newValue = "new test value"; it("Create Configs", () => { - cy.createConfigs(globalState, key, value); - cy.fetchConfigs(globalState, key, value); + cy.setConfigs(globalState, key, value, "CREATE"); + cy.setConfigs(globalState, key, value, "FETCH"); }); it("Update Configs", () => { - cy.updateConfigs(globalState, key, newValue); - cy.fetchConfigs(globalState, key, newValue); + cy.setConfigs(globalState, key, newValue, "UPDATE"); + cy.setConfigs(globalState, key, newValue, "FETCH"); }); it("delete configs", () => { - cy.deleteConfigs(globalState, key, newValue); + cy.setConfigs(globalState, key, newValue, "DELETE"); }); }); }); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00000-CoreFlows.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00000-CoreFlows.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00000-CoreFlows.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00000-CoreFlows.cy.js index a0e2ad643e8..b64bfc42546 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00000-CoreFlows.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00000-CoreFlows.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import { payment_methods_enabled } from "../PaymentUtils/Commons"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import { payment_methods_enabled } from "../../configs/Payment/Commons"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00001-AccountCreate.cy.js similarity index 84% rename from cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00001-AccountCreate.cy.js index 1788a369faf..8557c6c3c8e 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00001-AccountCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00001-AccountCreate.cy.js @@ -1,5 +1,5 @@ -import * as fixtures from "../../fixtures/imports"; -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/00002-CustomerCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00002-CustomerCreate.cy.js similarity index 81% rename from cypress-tests/cypress/e2e/PaymentTest/00002-CustomerCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00002-CustomerCreate.cy.js index cfc55ceef9d..ca64eb0c3f2 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00002-CustomerCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00002-CustomerCreate.cy.js @@ -1,5 +1,5 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00003-ConnectorCreate.cy.js similarity index 84% rename from cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00003-ConnectorCreate.cy.js index 3d002740e60..cde959ad8ea 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00003-ConnectorCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00003-ConnectorCreate.cy.js @@ -1,7 +1,7 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import { payment_methods_enabled } from "../PaymentUtils/Commons"; -import * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import { payment_methods_enabled } from "../../configs/Payment/Commons"; +import * as utils from "../../configs/Payment/Utils"; let globalState; describe("Connector Account Create flow test", () => { diff --git a/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00004-NoThreeDSAutoCapture.cy.js similarity index 95% rename from cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00004-NoThreeDSAutoCapture.cy.js index e5030647cb7..c2f5bb10828 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00004-NoThreeDSAutoCapture.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00004-NoThreeDSAutoCapture.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00005-ThreeDSAutoCapture.cy.js similarity index 89% rename from cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00005-ThreeDSAutoCapture.cy.js index 3a0b635f79a..715d4238679 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00005-ThreeDSAutoCapture.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00005-ThreeDSAutoCapture.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00006-NoThreeDSManualCapture.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00006-NoThreeDSManualCapture.cy.js index d9769daab4b..f82284b569f 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00006-NoThreeDSManualCapture.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00006-NoThreeDSManualCapture.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00007-VoidPayment.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00007-VoidPayment.cy.js index 68582a8e9aa..c298f164838 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00007-VoidPayment.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00007-VoidPayment.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00008-SyncPayment.cy.js similarity index 89% rename from cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00008-SyncPayment.cy.js index 370d811ed62..c7da98909a9 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00008-SyncPayment.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00008-SyncPayment.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00009-RefundPayment.cy.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00009-RefundPayment.cy.js index 4d534127ada..1d7ac32f0ba 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00009-RefundPayment.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00009-RefundPayment.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00010-SyncRefund.cy.js similarity index 92% rename from cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00010-SyncRefund.cy.js index dc738621166..db63105d830 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00010-SyncRefund.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00010-SyncRefund.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00011-CreateSingleuseMandate.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00011-CreateSingleuseMandate.cy.js index da2123d6462..6fa01f91991 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00011-CreateSingleuseMandate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00011-CreateSingleuseMandate.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00012-CreateMultiuseMandate.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00012-CreateMultiuseMandate.cy.js index 000d69c45e6..2af0b801d2d 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00012-CreateMultiuseMandate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00012-CreateMultiuseMandate.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00013-ListAndRevokeMandate.cy.js similarity index 94% rename from cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00013-ListAndRevokeMandate.cy.js index b8d0a51879d..f3704b84f97 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00013-ListAndRevokeMandate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00013-ListAndRevokeMandate.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00014-SaveCardFlow.cy.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00014-SaveCardFlow.cy.js index bab24076f55..26c250a3237 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00014-SaveCardFlow.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00014-SaveCardFlow.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; let saveCardBody; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00015-ZeroAuthMandate.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00015-ZeroAuthMandate.cy.js index 0cc1be50318..ba522b3cd71 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00015-ZeroAuthMandate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00015-ZeroAuthMandate.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00016-ThreeDSManualCapture.cy.js similarity index 94% rename from cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00016-ThreeDSManualCapture.cy.js index 0426d17013c..89d82f7fb93 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00016-ThreeDSManualCapture.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00016-ThreeDSManualCapture.cy.js @@ -1,7 +1,6 @@ -import captureBody from "../../fixtures/capture-flow-body.json"; -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; @@ -76,7 +75,7 @@ describe("Card - ThreeDS Manual payment flow test", () => { "card_pm" ]["Capture"]; - cy.captureCallTest(captureBody, data, 6500, globalState); + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); if (shouldContinue) shouldContinue = utils.should_continue_further(data); @@ -136,7 +135,7 @@ describe("Card - ThreeDS Manual payment flow test", () => { "card_pm" ]["Capture"]; - cy.captureCallTest(captureBody, data, 6500, globalState); + cy.captureCallTest(fixtures.captureBody, data, 6500, globalState); if (shouldContinue) shouldContinue = utils.should_continue_further(data); @@ -214,7 +213,7 @@ describe("Card - ThreeDS Manual payment flow test", () => { "card_pm" ]["PartialCapture"]; - cy.captureCallTest(captureBody, data, 100, globalState); + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); if (shouldContinue) shouldContinue = utils.should_continue_further(data); @@ -274,7 +273,7 @@ describe("Card - ThreeDS Manual payment flow test", () => { "card_pm" ]["PartialCapture"]; - cy.captureCallTest(captureBody, data, 100, globalState); + cy.captureCallTest(fixtures.captureBody, data, 100, globalState); if (shouldContinue) shouldContinue = utils.should_continue_further(data); diff --git a/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00017-BankTransfers.cy.js similarity index 91% rename from cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00017-BankTransfers.cy.js index 913dd91ea8b..49f93aaa10f 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00017-BankTransfers.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00017-BankTransfers.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00018-BankRedirect.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00018-BankRedirect.cy.js index cc3b8dbaec7..4a7fc840362 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00018-BankRedirect.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00018-BankRedirect.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00019-MandatesUsingPMID.cy.js similarity index 98% rename from cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00019-MandatesUsingPMID.cy.js index 1a2dff1b5da..ec8ddc6c700 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00019-MandatesUsingPMID.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00019-MandatesUsingPMID.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTIDProxy.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00020-MandatesUsingNTIDProxy.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTIDProxy.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00020-MandatesUsingNTIDProxy.cy.js index e3080d39878..1554436abfb 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00020-MandatesUsingNTIDProxy.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00020-MandatesUsingNTIDProxy.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; let connector; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00021-UPI.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00021-UPI.cy.js index e7a06c62248..d6b1c99407f 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00021-UPI.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00021-UPI.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00022-Variations.cy.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00022-Variations.cy.js index be594e76487..f1499dc93bd 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00022-Variations.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00022-Variations.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; let paymentIntentBody; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00023-PaymentMethods.cy.js similarity index 94% rename from cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00023-PaymentMethods.cy.js index 28262d025c4..d88be298896 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00023-PaymentMethods.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00023-PaymentMethods.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnosticNTID.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00024-ConnectorAgnosticNTID.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnosticNTID.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00024-ConnectorAgnosticNTID.cy.js index db5757e464c..4db0ad99900 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00024-ConnectorAgnosticNTID.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00024-ConnectorAgnosticNTID.cy.js @@ -1,7 +1,7 @@ -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"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import { payment_methods_enabled } from "../../configs/Payment/Commons"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00024-SessionCall.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00025-SessionCall.cy.js similarity index 87% rename from cypress-tests/cypress/e2e/PaymentTest/00024-SessionCall.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00025-SessionCall.cy.js index 8d729a2f77f..5a62f5f1a68 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00024-SessionCall.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00025-SessionCall.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00025-BusinessProfileConfigs.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00026-BusinessProfileConfigs.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PaymentTest/00025-BusinessProfileConfigs.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00026-BusinessProfileConfigs.cy.js index b1ccc55ccb3..e6e6030d1b9 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00025-BusinessProfileConfigs.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00026-BusinessProfileConfigs.cy.js @@ -1,7 +1,7 @@ -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"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import { payment_methods_enabled } from "../../configs/Payment/Commons"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00027-DynamicFields.cy.js similarity index 95% rename from cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00027-DynamicFields.cy.js index a325ac5f2f0..9bbf07b8808 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00026-DynamicFields.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00027-DynamicFields.cy.js @@ -1,7 +1,7 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import { cardCreditEnabled } from "../PaymentMethodListUtils/Commons"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; +import { cardCreditEnabled } from "../../configs/PaymentMethodList/Commons"; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js b/cypress-tests/cypress/e2e/spec/Payment/00028-IncrementalAuth.cy.js similarity index 95% rename from cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js rename to cypress-tests/cypress/e2e/spec/Payment/00028-IncrementalAuth.cy.js index e281fc0a2f7..76116acc2be 100644 --- a/cypress-tests/cypress/e2e/PaymentTest/00027-IncrementalAuth.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payment/00028-IncrementalAuth.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import getConnectorDetails, * as utils from "../PaymentUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import getConnectorDetails, * as utils from "../../configs/Payment/Utils"; let connector; let globalState; diff --git a/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js b/cypress-tests/cypress/e2e/spec/PaymentMethodList/00000-PaymentMethodListTests.cy.js similarity index 99% rename from cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js rename to cypress-tests/cypress/e2e/spec/PaymentMethodList/00000-PaymentMethodListTests.cy.js index 0f754831d46..292f5d06790 100644 --- a/cypress-tests/cypress/e2e/PaymentMethodListTest/00000-PaymentMethodListTests.cy.js +++ b/cypress-tests/cypress/e2e/spec/PaymentMethodList/00000-PaymentMethodListTests.cy.js @@ -1,16 +1,16 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; import { bankRedirectIdealAndCreditEnabled, bankRedirectIdealEnabled, cardCreditEnabled, + cardCreditEnabledInEur, cardCreditEnabledInUs, cardCreditEnabledInUsd, - cardCreditEnabledInEur, createPaymentBodyWithCurrency, createPaymentBodyWithCurrencyCountry, -} from "../PaymentMethodListUtils/Commons"; -import getConnectorDetails from "../PaymentMethodListUtils/Utils"; +} from "../../configs/PaymentMethodList/Commons"; +import getConnectorDetails from "../../configs/PaymentMethodList/Utils"; let globalState; describe("Payment Method list using Constraint Graph flow tests", () => { diff --git a/cypress-tests/cypress/e2e/PayoutTest/00000-AccountCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00000-AccountCreate.cy.js similarity index 84% rename from cypress-tests/cypress/e2e/PayoutTest/00000-AccountCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00000-AccountCreate.cy.js index 75cc93a4984..4b04db2ae01 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00000-AccountCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00000-AccountCreate.cy.js @@ -1,5 +1,5 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; let globalState; diff --git a/cypress-tests/cypress/e2e/PayoutTest/00001-CustomerCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00001-CustomerCreate.cy.js similarity index 81% rename from cypress-tests/cypress/e2e/PayoutTest/00001-CustomerCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00001-CustomerCreate.cy.js index cfc55ceef9d..ca64eb0c3f2 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00001-CustomerCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00001-CustomerCreate.cy.js @@ -1,5 +1,5 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; let globalState; diff --git a/cypress-tests/cypress/e2e/PayoutTest/00002-ConnectorCreate.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00002-ConnectorCreate.cy.js similarity index 83% rename from cypress-tests/cypress/e2e/PayoutTest/00002-ConnectorCreate.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00002-ConnectorCreate.cy.js index 8bcff83685e..ec7ee369930 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00002-ConnectorCreate.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00002-ConnectorCreate.cy.js @@ -1,5 +1,5 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; let globalState; describe("Connector Account Create flow test", () => { diff --git a/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00003-CardTest.cy.js similarity index 94% rename from cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00003-CardTest.cy.js index fd9b9d9f6e2..694a26b703c 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00003-CardTest.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00003-CardTest.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../PayoutUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Payout/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00004-BankTransfer.cy.js similarity index 96% rename from cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00004-BankTransfer.cy.js index 0cb4508ded8..174b257a482 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00004-BankTransfer.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00004-BankTransfer.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../PayoutUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Payout/Utils"; let globalState; diff --git a/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js b/cypress-tests/cypress/e2e/spec/Payout/00005-SavePayout.cy.js similarity index 97% rename from cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js rename to cypress-tests/cypress/e2e/spec/Payout/00005-SavePayout.cy.js index 37dc1c2cdf0..30ad8e6bf8d 100644 --- a/cypress-tests/cypress/e2e/PayoutTest/00005-SavePayout.cy.js +++ b/cypress-tests/cypress/e2e/spec/Payout/00005-SavePayout.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../PayoutUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Payout/Utils"; let globalState; let payoutBody; diff --git a/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js b/cypress-tests/cypress/e2e/spec/Routing/00000-PriorityRouting.cy.js similarity index 84% rename from cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js rename to cypress-tests/cypress/e2e/spec/Routing/00000-PriorityRouting.cy.js index 5699712ec2e..a070592d767 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00000-PriorityRouting.cy.js +++ b/cypress-tests/cypress/e2e/spec/Routing/00000-PriorityRouting.cy.js @@ -1,6 +1,6 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../RoutingUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Routing/Utils"; let globalState; @@ -8,11 +8,29 @@ describe("Priority Based Routing Test", () => { let shouldContinue = true; beforeEach(() => { - // Restore the session if it exists cy.session("login", () => { - cy.userLogin(globalState); - cy.terminate2Fa(globalState); - cy.userInfo(globalState); + // Make sure we have credentials + if (!globalState.get("email") || !globalState.get("password")) { + throw new Error("Missing login credentials in global state"); + } + + cy.userLogin(globalState) + .then(() => cy.terminate2Fa(globalState)) + .then(() => cy.userInfo(globalState)) + .then(() => { + // Verify we have all necessary tokens and IDs + const requiredKeys = [ + "userInfoToken", + "merchantId", + "organizationId", + "profileId", + ]; + requiredKeys.forEach((key) => { + if (!globalState.get(key)) { + throw new Error(`Missing required key after login: ${key}`); + } + }); + }); }); }); diff --git a/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js b/cypress-tests/cypress/e2e/spec/Routing/00001-VolumeBasedRouting.cy.js similarity index 87% rename from cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js rename to cypress-tests/cypress/e2e/spec/Routing/00001-VolumeBasedRouting.cy.js index 16b640bc03d..75d5b7ab840 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00001-VolumeBasedRouting.cy.js +++ b/cypress-tests/cypress/e2e/spec/Routing/00001-VolumeBasedRouting.cy.js @@ -1,16 +1,35 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../RoutingUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Routing/Utils"; let globalState; describe("Volume Based Routing Test", () => { + // Restore the session if it exists beforeEach(() => { - // Restore the session if it exists cy.session("login", () => { - cy.userLogin(globalState); - cy.terminate2Fa(globalState); - cy.userInfo(globalState); + // Make sure we have credentials + if (!globalState.get("email") || !globalState.get("password")) { + throw new Error("Missing login credentials in global state"); + } + + cy.userLogin(globalState) + .then(() => cy.terminate2Fa(globalState)) + .then(() => cy.userInfo(globalState)) + .then(() => { + // Verify we have all necessary tokens and IDs + const requiredKeys = [ + "userInfoToken", + "merchantId", + "organizationId", + "profileId", + ]; + requiredKeys.forEach((key) => { + if (!globalState.get(key)) { + throw new Error(`Missing required key after login: ${key}`); + } + }); + }); }); }); diff --git a/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js b/cypress-tests/cypress/e2e/spec/Routing/00002-RuleBasedRouting.cy.js similarity index 93% rename from cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js rename to cypress-tests/cypress/e2e/spec/Routing/00002-RuleBasedRouting.cy.js index a1621a530ae..cf18a20487d 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00002-RuleBasedRouting.cy.js +++ b/cypress-tests/cypress/e2e/spec/Routing/00002-RuleBasedRouting.cy.js @@ -1,16 +1,35 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../RoutingUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Routing/Utils"; let globalState; describe("Rule Based Routing Test", () => { + // Restore the session if it exists beforeEach(() => { - // Restore the session if it exists cy.session("login", () => { - cy.userLogin(globalState); - cy.terminate2Fa(globalState); - cy.userInfo(globalState); + // Make sure we have credentials + if (!globalState.get("email") || !globalState.get("password")) { + throw new Error("Missing login credentials in global state"); + } + + cy.userLogin(globalState) + .then(() => cy.terminate2Fa(globalState)) + .then(() => cy.userInfo(globalState)) + .then(() => { + // Verify we have all necessary tokens and IDs + const requiredKeys = [ + "userInfoToken", + "merchantId", + "organizationId", + "profileId", + ]; + requiredKeys.forEach((key) => { + if (!globalState.get(key)) { + throw new Error(`Missing required key after login: ${key}`); + } + }); + }); }); }); diff --git a/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js b/cypress-tests/cypress/e2e/spec/Routing/00003-Retries.cy.js similarity index 79% rename from cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js rename to cypress-tests/cypress/e2e/spec/Routing/00003-Retries.cy.js index 94fcaed104d..0e4eaed7c31 100644 --- a/cypress-tests/cypress/e2e/RoutingTest/00003-Retries.cy.js +++ b/cypress-tests/cypress/e2e/spec/Routing/00003-Retries.cy.js @@ -1,16 +1,35 @@ -import * as fixtures from "../../fixtures/imports"; -import State from "../../utils/State"; -import * as utils from "../RoutingUtils/Utils"; +import * as fixtures from "../../../fixtures/imports"; +import State from "../../../utils/State"; +import * as utils from "../../configs/Routing/Utils"; let globalState; describe("Auto Retries & Step Up 3DS", () => { + // Restore the session if it exists beforeEach(() => { - // Restore the session if it exists cy.session("login", () => { - cy.userLogin(globalState); - cy.terminate2Fa(globalState); - cy.userInfo(globalState); + // Make sure we have credentials + if (!globalState.get("email") || !globalState.get("password")) { + throw new Error("Missing login credentials in global state"); + } + + cy.userLogin(globalState) + .then(() => cy.terminate2Fa(globalState)) + .then(() => cy.userInfo(globalState)) + .then(() => { + // Verify we have all necessary tokens and IDs + const requiredKeys = [ + "userInfoToken", + "merchantId", + "organizationId", + "profileId", + ]; + requiredKeys.forEach((key) => { + if (!globalState.get(key)) { + throw new Error(`Missing required key after login: ${key}`); + } + }); + }); }); }); @@ -45,7 +64,13 @@ describe("Auto Retries & Step Up 3DS", () => { context("Auto Retries", () => { context("[Config: enable] Auto retries", () => { it("Enable auto retries", () => { - cy.updateConfig("autoRetry", globalState, "true"); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `should_call_gsm_${merchantId}`, + "true", + "UPDATE" + ); }); context("Max auto retries", () => { @@ -96,9 +121,15 @@ describe("Auto Retries & Step Up 3DS", () => { }); context("Max auto retries = 2", () => { - const max_auto_retries = 2; + const maxAutoRetries = 2; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -136,16 +167,22 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); }); context("Max auto retries = 1", () => { - const max_auto_retries = 1; + const maxAutoRetries = 1; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -183,15 +220,21 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); }); context("Max auto retries = 0", () => { - const max_auto_retries = 0; + const maxAutoRetries = 0; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -229,7 +272,7 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); @@ -283,9 +326,15 @@ describe("Auto Retries & Step Up 3DS", () => { }); context("Max auto retries = 2", () => { - const max_auto_retries = 2; + const maxAutoRetries = 2; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -323,16 +372,22 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); }); context("Max auto retries = 1", () => { - const max_auto_retries = 1; + const maxAutoRetries = 1; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -370,16 +425,22 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); }); context("Max auto retries = 0", () => { - const max_auto_retries = 0; + const maxAutoRetries = 0; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); context("Make payment", () => { @@ -417,7 +478,7 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); @@ -432,14 +493,26 @@ describe("Auto Retries & Step Up 3DS", () => { }); it("[Config: enable] Step up for Stripe", () => { - cy.updateConfig("stepUp", globalState, '["stripe"]'); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `step_up_enabled_${merchantId}`, + '["stripe"]', + "UPDATE" + ); }); }); context("Make Payment", () => { - const max_auto_retries = 1; + const maxAutoRetries = 1; it("Update max auto retries", () => { - cy.updateConfig("maxRetries", globalState, `${max_auto_retries}`); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `max_auto_retries_enabled_${merchantId}`, + `${maxAutoRetries}`, + "UPDATE" + ); }); it("Payment create call", () => { @@ -471,7 +544,7 @@ describe("Auto Retries & Step Up 3DS", () => { globalState, null, true, - max_auto_retries + 1 + maxAutoRetries + 1 ); }); }); @@ -480,7 +553,13 @@ describe("Auto Retries & Step Up 3DS", () => { context("[Config: disable] Auto retries", () => { it("[Config: disable] Auto retries", () => { - cy.updateConfig("autoRetry", globalState, "false"); + const merchantId = globalState.get("merchantId"); + cy.setConfigs( + globalState, + `should_call_gsm_${merchantId}`, + "false", + "UPDATE" + ); }); it("[Config: disable] Step up GSM", () => { diff --git a/cypress-tests/cypress/support/commands.js b/cypress-tests/cypress/support/commands.js index 1b7b41a035d..60691899f7c 100644 --- a/cypress-tests/cypress/support/commands.js +++ b/cypress-tests/cypress/support/commands.js @@ -29,9 +29,10 @@ import { defaultErrorHandler, extractIntegerAtEnd, getValueByKey, -} from "../e2e/PaymentUtils/Utils"; +} from "../e2e/configs/Payment/Utils"; import { execConfig, validateConfig } from "../utils/featureFlags"; import * as RequestBodyUtils from "../utils/RequestBodyUtils"; +import { isoTimeTomorrow, validateEnv } from "../utils/RequestBodyUtils.js"; import { handleRedirection } from "./redirectionHandler"; function logRequestId(xRequestId) { @@ -44,11 +45,36 @@ function logRequestId(xRequestId) { function validateErrorMessage(response, resData) { if (resData.body.status !== "failed") { - expect(response.body.error_message).to.be.null; - expect(response.body.error_code).to.be.null; + expect(response.body.error_message, "error_message").to.be.null; + expect(response.body.error_code, "error_code").to.be.null; } } +Cypress.Commands.add("healthCheck", (globalState) => { + const baseUrl = globalState.get("baseUrl"); + const url = `${baseUrl}/health`; + + cy.request({ + method: "GET", + url: url, + headers: { + Accept: "application/json", + }, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body).to.equal("health is good"); + } else { + throw new Error( + `Health Check failed with status: \`${response.status}\` and body: \`${response.body}\`` + ); + } + }); + }); +}); + Cypress.Commands.add( "merchantCreateCallTest", (merchantCreateBody, globalState) => { @@ -68,10 +94,12 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - // Handle the response as needed - globalState.set("profileId", response.body.default_profile); - globalState.set("publishableKey", response.body.publishable_key); - globalState.set("merchantDetails", response.body.merchant_details); + cy.wrap(response).then(() => { + // Handle the response as needed + globalState.set("profileId", response.body.default_profile); + globalState.set("publishableKey", response.body.publishable_key); + globalState.set("merchantDetails", response.body.merchant_details); + }); }); } ); @@ -90,17 +118,19 @@ Cypress.Commands.add("merchantRetrieveCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.payment_response_hash_key).to.not.be.empty; - expect(response.body.publishable_key).to.not.be.empty; - expect(response.body.default_profile).to.not.be.empty; - expect(response.body.organization_id).to.not.be.empty; - globalState.set("organizationId", response.body.organization_id); - - if (globalState.get("publishableKey") === undefined) { - globalState.set("publishableKey", response.body.publishable_key); - } + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.payment_response_hash_key).to.not.be.empty; + expect(response.body.publishable_key).to.not.be.empty; + expect(response.body.default_profile).to.not.be.empty; + expect(response.body.organization_id).to.not.be.empty; + globalState.set("organizationId", response.body.organization_id); + + if (globalState.get("publishableKey") === undefined) { + globalState.set("publishableKey", response.body.publishable_key); + } + }); }); }); @@ -117,8 +147,10 @@ Cypress.Commands.add("merchantDeleteCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.deleted).to.equal(true); + cy.wrap(response).then(() => { + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.deleted).to.equal(true); + }); }); }); @@ -135,12 +167,15 @@ Cypress.Commands.add("ListConnectorsFeatureMatrixCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body).to.have.property("connectors").and.not.empty; - expect(response.body.connectors).to.be.an("array").and.not.empty; - response.body.connectors.forEach((item) => { - expect(item).to.have.property("description").and.not.empty; - expect(item).to.have.property("category").and.not.empty; - expect(item).to.have.property("supported_payment_methods").and.not.empty; + cy.wrap(response).then(() => { + expect(response.body).to.have.property("connectors").and.not.empty; + expect(response.body.connectors).to.be.an("array").and.not.empty; + response.body.connectors.forEach((item) => { + expect(item).to.have.property("description").and.not.empty; + expect(item).to.have.property("category").and.not.empty; + expect(item).to.have.property("supported_payment_methods").and.not + .empty; + }); }); }); }); @@ -158,14 +193,18 @@ Cypress.Commands.add("merchantListCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - for (const key in response.body) { - expect(response.body[key]).to.have.property("merchant_id").and.not.empty; - expect(response.body[key]).to.have.property("organization_id").and.not - .empty; - expect(response.body[key]).to.have.property("default_profile").and.not - .empty; - } + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + for (const key in response.body) { + expect(response.body[key]).to.have.property("merchant_id").and.not + .empty; + expect(response.body[key]).to.have.property("organization_id").and.not + .empty; + expect(response.body[key]).to.have.property("default_profile").and.not + .empty; + } + }); }); }); @@ -190,11 +229,14 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.publishable_key).to.equal(publishable_key); - expect(response.body.organization_id).to.equal(organization_id); - expect(response.body.merchant_details).to.not.equal(merchant_details); + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.publishable_key).to.equal(publishable_key); + expect(response.body.organization_id).to.equal(organization_id); + expect(response.body.merchant_details).to.not.equal(merchant_details); + }); }); } ); @@ -224,15 +266,16 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - globalState.set(`${profilePrefix}Id`, response.body.profile_id); - - if (response.status === 200) { - expect(response.body.profile_id).to.not.to.be.null; - } else { - throw new Error( - `Business Profile call failed ${response.body.error.message}` - ); - } + cy.wrap(response).then(() => { + globalState.set(`${profilePrefix}Id`, response.body.profile_id); + if (response.status === 200) { + expect(response.body.profile_id).to.not.to.be.null; + } else { + throw new Error( + `Business Profile call failed ${response.body.error.message}` + ); + } + }); }); } ); @@ -276,55 +319,98 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - globalState.set( - "collectBillingDetails", - response.body.collect_billing_details_from_wallet_connector - ); - globalState.set( - "collectShippingDetails", - response.body.collect_shipping_details_from_wallet_connector - ); - globalState.set( - "alwaysCollectBillingDetails", - response.body.always_collect_billing_details_from_wallet_connector - ); - globalState.set( - "alwaysCollectShippingDetails", - response.body.always_collect_shipping_details_from_wallet_connector - ); - } + + cy.wrap(response).then(() => { + if (response.status === 200) { + globalState.set( + "collectBillingDetails", + response.body.collect_billing_details_from_wallet_connector + ); + globalState.set( + "collectShippingDetails", + response.body.collect_shipping_details_from_wallet_connector + ); + globalState.set( + "alwaysCollectBillingDetails", + response.body.always_collect_billing_details_from_wallet_connector + ); + globalState.set( + "alwaysCollectShippingDetails", + response.body.always_collect_shipping_details_from_wallet_connector + ); + } + }); }); } ); - +// API Key API calls Cypress.Commands.add("apiKeyCreateTest", (apiKeyCreateBody, globalState) => { + // Define the necessary variables and constant + + const apiKey = globalState.get("adminApiKey"); + const baseUrl = globalState.get("baseUrl"); + // We do not want to keep API Key forever, + // so we set the expiry to tomorrow as new merchant accounts are created with every run + const expiry = isoTimeTomorrow(); + const keyIdType = "key_id"; + const keyId = validateEnv(baseUrl, keyIdType); + const merchantId = globalState.get("merchantId"); + const url = `${baseUrl}/api_keys/${merchantId}`; + + // Update request body + apiKeyCreateBody.expiration = expiry; + cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/api_keys/${globalState.get("merchantId")}`, + url: url, headers: { Accept: "application/json", "Content-Type": "application/json", - "api-key": globalState.get("adminApiKey"), + "api-key": apiKey, }, body: apiKeyCreateBody, failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - // Handle the response as needed - globalState.set("apiKey", response.body.api_key); - globalState.set("apiKeyId", response.body.key_id); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body.merchant_id).to.equal(merchantId); + expect(response.body.description).to.equal( + apiKeyCreateBody.description + ); + + // API Key assertions are intentionally excluded to avoid being exposed in the logs + expect(response.body).to.have.property(keyIdType).and.to.include(keyId) + .and.to.not.be.empty; + + globalState.set("apiKeyId", response.body.key_id); + globalState.set("apiKey", response.body.api_key); + + cy.task("setGlobalState", globalState.data); + } else { + // to be updated + throw new Error( + `API Key create call failed with status ${response.status} and message: "${response.body.error.message}"` + ); + } + }); }); }); Cypress.Commands.add("apiKeyUpdateCall", (apiKeyUpdateBody, globalState) => { - const merchant_id = globalState.get("merchantId"); - const api_key_id = globalState.get("apiKeyId"); + const merchantId = globalState.get("merchantId"); + const apiKeyId = globalState.get("apiKeyId"); + // We do not want to keep API Key forever, + // so we set the expiry to tomorrow as new merchant accounts are created with every run + const expiry = isoTimeTomorrow(); + + // Update request body + apiKeyUpdateBody.expiration = expiry; cy.request({ method: "POST", - url: `${globalState.get("baseUrl")}/api_keys/${merchant_id}/${api_key_id}`, + url: `${globalState.get("baseUrl")}/api_keys/${merchantId}/${apiKeyId}`, headers: { Accept: "application/json", "Content-Type": "application/json", @@ -335,10 +421,20 @@ Cypress.Commands.add("apiKeyUpdateCall", (apiKeyUpdateBody, globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - // Handle the response as needed - expect(response.body.name).to.equal("Updated API Key"); - expect(response.body.key_id).to.equal(api_key_id); - expect(response.body.merchant_id).to.equal(merchant_id); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body.name).to.equal("Updated API Key"); + expect(response.body.merchant_id).to.equal(merchantId); + + // API Key assertions are intentionally excluded to avoid being exposed in the logs + expect(response.body.key_id).to.equal(apiKeyId); + } else { + // to be updated + throw new Error( + `API Key create call failed with status ${response.status} and message: "${response.body.error.message}"` + ); + } + }); }); }); @@ -358,10 +454,12 @@ Cypress.Commands.add("apiKeyRetrieveCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.name).to.equal("Updated API Key"); - expect(response.body.key_id).to.equal(api_key_id); - expect(response.body.merchant_id).to.equal(merchant_id); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.name).to.equal("Updated API Key"); + expect(response.body.key_id).to.equal(api_key_id); + expect(response.body.merchant_id).to.equal(merchant_id); + }); }); }); @@ -379,19 +477,21 @@ Cypress.Commands.add("apiKeyListCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body).to.be.an("array").and.not.empty; - for (const key in response.body) { - expect(response.body[key]).to.have.property("name").and.not.empty; - if (base_url.includes("sandbox") || base_url.includes("integ")) { - expect(response.body[key]).to.have.property("key_id").include("snd_") - .and.not.empty; - } else if (base_url.includes("localhost")) { - expect(response.body[key]).to.have.property("key_id").include("dev_") - .and.not.empty; + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.be.an("array").and.not.empty; + for (const key in response.body) { + expect(response.body[key]).to.have.property("name").and.not.empty; + if (base_url.includes("sandbox") || base_url.includes("integ")) { + expect(response.body[key]).to.have.property("key_id").include("snd_") + .and.not.empty; + } else if (base_url.includes("localhost")) { + expect(response.body[key]).to.have.property("key_id").include("dev_") + .and.not.empty; + } + expect(response.body[key].merchant_id).to.equal(merchant_id); } - expect(response.body[key].merchant_id).to.equal(merchant_id); - } + }); }); }); @@ -411,10 +511,12 @@ Cypress.Commands.add("apiKeyDeleteCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.key_id).to.equal(api_key_id); - expect(response.body.revoked).to.equal(true); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.key_id).to.equal(api_key_id); + expect(response.body.revoked).to.equal(true); + }); }); }); @@ -461,22 +563,24 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(connectorName).to.equal(response.body.connector_name); - globalState.set( - `${mcaPrefix}Id`, - response.body.merchant_connector_id - ); - } else { - cy.task( - "cli_log", - "response status -> " + JSON.stringify(response.status) - ); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(connectorName).to.equal(response.body.connector_name); + globalState.set( + `${mcaPrefix}Id`, + response.body.merchant_connector_id + ); + } else { + cy.task( + "cli_log", + "response status -> " + JSON.stringify(response.status) + ); - throw new Error( - `Connector Create Call Failed ${response.body.error.message}` - ); - } + throw new Error( + `Connector Create Call Failed ${response.body.error.message}` + ); + } + }); }); } ); @@ -546,24 +650,26 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(globalState.get("connectorId")).to.equal( - response.body.connector_name - ); - globalState.set( - `${mcaPrefix}Id`, - response.body.merchant_connector_id - ); - } else { - cy.task( - "cli_log", - "response status -> " + JSON.stringify(response.status) - ); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(globalState.get("connectorId")).to.equal( + response.body.connector_name + ); + globalState.set( + `${mcaPrefix}Id`, + response.body.merchant_connector_id + ); + } else { + cy.task( + "cli_log", + "response status -> " + JSON.stringify(response.status) + ); - throw new Error( - `Connector Create Call Failed ${response.body.error.message}` - ); - } + throw new Error( + `Connector Create Call Failed ${response.body.error.message}` + ); + } + }); }); } ); @@ -620,24 +726,26 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(globalState.get("connectorId")).to.equal( - response.body.connector_name - ); - globalState.set( - "merchantConnectorId", - response.body.merchant_connector_id - ); - } else { - cy.task( - "cli_log", - "response status -> " + JSON.stringify(response.status) - ); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(globalState.get("connectorId")).to.equal( + response.body.connector_name + ); + globalState.set( + "merchantConnectorId", + response.body.merchant_connector_id + ); + } else { + cy.task( + "cli_log", + "response status -> " + JSON.stringify(response.status) + ); - throw new Error( - `Connector Create Call Failed ${response.body.error.message}` - ); - } + throw new Error( + `Connector Create Call Failed ${response.body.error.message}` + ); + } + }); }); } ); @@ -661,9 +769,14 @@ Cypress.Commands.add("connectorRetrieveCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.connector_name).to.equal(connector_id); - expect(response.body.merchant_connector_id).to.equal(merchant_connector_id); + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.connector_name).to.equal(connector_id); + expect(response.body.merchant_connector_id).to.equal( + merchant_connector_id + ); + }); }); }); @@ -682,9 +795,13 @@ Cypress.Commands.add("connectorDeleteCall", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.merchant_connector_id).to.equal(merchant_connector_id); - expect(response.body.deleted).to.equal(true); + cy.wrap(response).then(() => { + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.merchant_connector_id).to.equal( + merchant_connector_id + ); + expect(response.body.deleted).to.equal(true); + }); }); }); @@ -715,12 +832,15 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.connector_name).to.equal(connector_id); - expect(response.body.merchant_connector_id).to.equal( - merchant_connector_id - ); - expect(response.body.connector_label).to.equal(connectorLabel); + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.connector_name).to.equal(connector_id); + expect(response.body.merchant_connector_id).to.equal( + merchant_connector_id + ); + expect(response.body.connector_label).to.equal(connectorLabel); + }); }); } ); @@ -739,12 +859,15 @@ Cypress.Commands.add("connectorListByMid", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body).to.be.an("array").and.not.empty; - response.body.forEach((item) => { - expect(item).to.not.have.property("metadata"); - expect(item).to.not.have.property("additional_merchant_data"); - expect(item).to.not.have.property("connector_wallets_details"); + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.be.an("array").and.not.empty; + response.body.forEach((item) => { + expect(item).to.not.have.property("metadata"); + expect(item).to.not.have.property("additional_merchant_data"); + expect(item).to.not.have.property("connector_wallets_details"); + }); }); }); }); @@ -763,20 +886,23 @@ Cypress.Commands.add( }).then((response) => { globalState.set("customerId", response.body.customer_id); logRequestId(response.headers["x-request-id"]); - expect(response.body.customer_id, "customer_id").to.not.be.empty; - expect(customerCreateBody.email, "email").to.equal(response.body.email); - expect(customerCreateBody.name, "name").to.equal(response.body.name); - expect(customerCreateBody.phone, "phone").to.equal(response.body.phone); - expect(customerCreateBody.metadata, "metadata").to.deep.equal( - response.body.metadata - ); - expect(customerCreateBody.address, "address").to.deep.equal( - response.body.address - ); - expect( - customerCreateBody.phone_country_code, - "phone_country_code" - ).to.equal(response.body.phone_country_code); + + cy.wrap(response).then(() => { + expect(response.body.customer_id, "customer_id").to.not.be.empty; + expect(customerCreateBody.email, "email").to.equal(response.body.email); + expect(customerCreateBody.name, "name").to.equal(response.body.name); + expect(customerCreateBody.phone, "phone").to.equal(response.body.phone); + expect(customerCreateBody.metadata, "metadata").to.deep.equal( + response.body.metadata + ); + expect(customerCreateBody.address, "address").to.deep.equal( + response.body.address + ); + expect( + customerCreateBody.phone_country_code, + "phone_country_code" + ).to.equal(response.body.phone_country_code); + }); }); } ); @@ -792,9 +918,12 @@ Cypress.Commands.add("customerListCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - for (const key in response.body) { - expect(response.body[key]).to.not.be.empty; - } + + cy.wrap(response).then(() => { + for (const key in response.body) { + expect(response.body[key]).to.not.be.empty; + } + }); }); }); @@ -811,7 +940,10 @@ Cypress.Commands.add("customerRetrieveCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.customer_id).to.equal(customer_id).and.not.be.empty; + + cy.wrap(response).then(() => { + expect(response.body.customer_id).to.equal(customer_id).and.not.be.empty; + }); }); }); @@ -831,7 +963,10 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.customer_id).to.equal(customer_id); + + cy.wrap(response).then(() => { + expect(response.body.customer_id).to.equal(customer_id); + }); }); } ); @@ -851,10 +986,13 @@ Cypress.Commands.add("ephemeralGenerateCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.customer_id).to.equal(customer_id); - expect(response.body.merchant_id).to.equal(merchant_id); - expect(response.body.id).to.exist.and.not.be.empty; - expect(response.body.secret).to.exist.and.not.be.empty; + + cy.wrap(response).then(() => { + expect(response.body.customer_id).to.equal(customer_id); + expect(response.body.merchant_id).to.equal(merchant_id); + expect(response.body.id).to.exist.and.not.be.empty; + expect(response.body.secret).to.exist.and.not.be.empty; + }); }); }); @@ -871,10 +1009,13 @@ Cypress.Commands.add("customerDeleteCall", (globalState) => { failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.body.customer_id).to.equal(customer_id).and.not.be.empty; - expect(response.body.customer_deleted).to.equal(true); - expect(response.body.address_deleted).to.equal(true); - expect(response.body.payment_methods_deleted).to.equal(true); + + cy.wrap(response).then(() => { + expect(response.body.customer_id).to.equal(customer_id).and.not.be.empty; + expect(response.body.customer_deleted).to.equal(true); + expect(response.body.address_deleted).to.equal(true); + expect(response.body.payment_methods_deleted).to.equal(true); + }); }); }); @@ -892,24 +1033,27 @@ Cypress.Commands.add( 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).to.have.property("currency"); - if (resData["payment_methods"].length == 1) { - function getPaymentMethodType(obj) { - return obj["payment_methods"][0]["payment_method_types"][0][ - "payment_method_type" - ]; + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + expect(response.body).to.have.property("currency"); + if (resData["payment_methods"].length == 1) { + function getPaymentMethodType(obj) { + return obj["payment_methods"][0]["payment_method_types"][0][ + "payment_method_type" + ]; + } + expect(getPaymentMethodType(resData)).to.equal( + getPaymentMethodType(response.body) + ); + } else { + expect(0).to.equal(response.body["payment_methods"].length); } - expect(getPaymentMethodType(resData)).to.equal( - getPaymentMethodType(response.body) - ); } else { - expect(0).to.equal(response.body["payment_methods"].length); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -933,41 +1077,43 @@ Cypress.Commands.add( 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 + cy.wrap(response).then(() => { + 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}"` ); - 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}"` - ); - } + } + }); }); } ); @@ -986,32 +1132,35 @@ Cypress.Commands.add( 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).to.have.property("currency"); - if (resData["payment_methods"].length > 0) { - function getPaymentMethodType(obj) { - return obj["payment_methods"][0]["payment_method_types"][0][ - "card_networks" - ][0]["eligible_connectors"] - .slice() - .sort(); - } - 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++) { - expect(config_payment_method_type[i]).to.equal( - response_payment_method_type[i] + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + expect(response.body).to.have.property("currency"); + if (resData["payment_methods"].length > 0) { + function getPaymentMethodType(obj) { + return obj["payment_methods"][0]["payment_method_types"][0][ + "card_networks" + ][0]["eligible_connectors"] + .slice() + .sort(); + } + 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++) { + expect(config_payment_method_type[i]).to.equal( + response_payment_method_type[i] + ); + } + } else { + expect(0).to.equal(response.body["payment_methods"].length); } } else { - expect(0).to.equal(response.body["payment_methods"].length); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1039,32 +1188,34 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - const expectedTokens = resData.body.session_token; - const actualTokens = response.body.session_token; + cy.wrap(response).then(() => { + if (response.status === 200) { + const expectedTokens = resData.body.session_token; + const actualTokens = response.body.session_token; - // Verifying length of array - expect(actualTokens.length, "arrayLength").to.equal( - expectedTokens.length - ); + // Verifying length of array + expect(actualTokens.length, "arrayLength").to.equal( + expectedTokens.length + ); - // Verify specific fields in each session_token object - expectedTokens.forEach((expectedToken, index) => { - const actualToken = actualTokens[index]; + // Verify specific fields in each session_token object + expectedTokens.forEach((expectedToken, index) => { + const actualToken = actualTokens[index]; - // Check specific fields only - expect(actualToken.wallet_name, "wallet_name").to.equal( - expectedToken.wallet_name - ); - expect(actualToken.connector, "connector").to.equal( - expectedToken.connector - ); - }); - } else { - defaultErrorHandler(response, resData); - } - }); - } + // Check specific fields only + expect(actualToken.wallet_name, "wallet_name").to.equal( + expectedToken.wallet_name + ); + expect(actualToken.connector, "connector").to.equal( + expectedToken.connector + ); + }); + } else { + defaultErrorHandler(response, resData); + } + }); + }); + } ); Cypress.Commands.add( @@ -1118,91 +1269,95 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - - 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 resData.body) { - expect(resData.body[key]).to.equal( - response.body[key], - `Expected ${resData.body[key]} but got ${response.body[key]}` + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + 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 resData.body) { + expect(resData.body[key]).to.equal( + response.body[key], + `Expected ${resData.body[key]} but got ${response.body[key]}` + ); + } + expect(response.body.payment_id, "payment_id").to.not.be.null; + expect(response.body.merchant_id, "merchant_id").to.not.be.null; + expect(createPaymentBody.amount, "amount").to.equal( + response.body.amount ); - } - expect(response.body.payment_id, "payment_id").to.not.be.null; - expect(response.body.merchant_id, "merchant_id").to.not.be.null; - expect(createPaymentBody.amount, "amount").to.equal( - response.body.amount - ); - expect(createPaymentBody.currency, "currency").to.equal( - response.body.currency - ); - expect(createPaymentBody.capture_method, "capture_method").to.equal( - response.body.capture_method - ); - expect( - createPaymentBody.authentication_type, - "authentication_type" - ).to.equal(response.body.authentication_type); - expect(createPaymentBody.description, "description").to.equal( - response.body.description - ); - expect(createPaymentBody.email, "email").to.equal(response.body.email); - expect(createPaymentBody.email, "customer.email").to.equal( - response.body.customer.email - ); - expect(createPaymentBody.customer_id, "customer.id").to.equal( - response.body.customer.id - ); - expect(createPaymentBody.metadata, "metadata").to.deep.equal( - response.body.metadata - ); - expect( - createPaymentBody.setup_future_usage, - "setup_future_usage" - ).to.equal(response.body.setup_future_usage); - // If 'shipping_cost' is not included in the request, the 'amount' in 'createPaymentBody' should match the 'amount_capturable' in the response. - if (typeof createPaymentBody?.shipping_cost === "undefined") { - expect(createPaymentBody.amount, "amount_capturable").to.equal( - response.body.amount_capturable + expect(createPaymentBody.currency, "currency").to.equal( + response.body.currency + ); + expect(createPaymentBody.capture_method, "capture_method").to.equal( + response.body.capture_method ); - } else { expect( - createPaymentBody.amount + createPaymentBody.shipping_cost, - "amount_capturable" - ).to.equal(response.body.amount_capturable); - } - expect(response.body.amount_received, "amount_received").to.be.oneOf([ - 0, - null, - ]); - expect(response.body.connector, "connector").to.be.null; - expect(createPaymentBody.capture_method, "capture_method").to.equal( - response.body.capture_method - ); - expect(response.body.payment_method, "payment_method").to.be.null; - expect(response.body.payment_method_data, "payment_method_data").to.be - .null; - expect(response.body.merchant_connector_id, "merchant_connector_id").to - .be.null; - expect(response.body.payment_method_id, "payment_method_id").to.be.null; - expect(response.body.payment_method_id, "payment_method_status").to.be - .null; - expect(response.body.profile_id, "profile_id").to.not.be.null; - expect( - response.body.merchant_order_reference_id, - "merchant_order_reference_id" - ).to.be.null; - expect(response.body.connector_mandate_id, "connector_mandate_id").to.be - .null; + createPaymentBody.authentication_type, + "authentication_type" + ).to.equal(response.body.authentication_type); + expect(createPaymentBody.description, "description").to.equal( + response.body.description + ); + expect(createPaymentBody.email, "email").to.equal( + response.body.email + ); + expect(createPaymentBody.email, "customer.email").to.equal( + response.body.customer.email + ); + expect(createPaymentBody.customer_id, "customer.id").to.equal( + response.body.customer.id + ); + expect(createPaymentBody.metadata, "metadata").to.deep.equal( + response.body.metadata + ); + expect( + createPaymentBody.setup_future_usage, + "setup_future_usage" + ).to.equal(response.body.setup_future_usage); + // If 'shipping_cost' is not included in the request, the 'amount' in 'createPaymentBody' should match the 'amount_capturable' in the response. + if (typeof createPaymentBody?.shipping_cost === "undefined") { + expect(createPaymentBody.amount, "amount_capturable").to.equal( + response.body.amount_capturable + ); + } else { + expect( + createPaymentBody.amount + createPaymentBody.shipping_cost, + "amount_capturable" + ).to.equal(response.body.amount_capturable); + } + expect(response.body.amount_received, "amount_received").to.be.oneOf([ + 0, + null, + ]); + expect(response.body.connector, "connector").to.be.null; + expect(createPaymentBody.capture_method, "capture_method").to.equal( + response.body.capture_method + ); + expect(response.body.payment_method, "payment_method").to.be.null; + expect(response.body.payment_method_data, "payment_method_data").to.be + .null; + expect(response.body.merchant_connector_id, "merchant_connector_id") + .to.be.null; + expect(response.body.payment_method_id, "payment_method_id").to.be + .null; + expect(response.body.payment_method_id, "payment_method_status").to.be + .null; + expect(response.body.profile_id, "profile_id").to.not.be.null; + expect( + response.body.merchant_order_reference_id, + "merchant_order_reference_id" + ).to.be.null; + expect(response.body.connector_mandate_id, "connector_mandate_id").to + .be.null; - validateErrorMessage(response, resData); - } else { - defaultErrorHandler(response, resData); - } + validateErrorMessage(response, resData); + } else { + defaultErrorHandler(response, resData); + } + }); }); } ); @@ -1221,38 +1376,40 @@ Cypress.Commands.add("paymentMethodsCallTest", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body).to.have.property("redirect_url"); - expect(response.body).to.have.property("payment_methods"); - if ( - globalState.get("collectBillingDetails") === true || - globalState.get("alwaysCollectBillingDetails") === true - ) { - expect( - response.body.collect_billing_details_from_wallets, - "collectBillingDetailsFromWallets" - ).to.be.true; - } else - expect( - response.body.collect_billing_details_from_wallets, - "collectBillingDetailsFromWallets" - ).to.be.false; + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body).to.have.property("redirect_url"); + expect(response.body).to.have.property("payment_methods"); + if ( + globalState.get("collectBillingDetails") === true || + globalState.get("alwaysCollectBillingDetails") === true + ) { + expect( + response.body.collect_billing_details_from_wallets, + "collectBillingDetailsFromWallets" + ).to.be.true; + } else + expect( + response.body.collect_billing_details_from_wallets, + "collectBillingDetailsFromWallets" + ).to.be.false; - if ( - globalState.get("collectShippingDetails") === true || - globalState.get("alwaysCollectShippingDetails") === true - ) { - expect( - response.body.collect_shipping_details_from_wallets, - "collectShippingDetailsFromWallets" - ).to.be.true; - } else - expect( - response.body.collect_shipping_details_from_wallets, - "collectShippingDetailsFromWallets" - ).to.be.false; - globalState.set("paymentID", paymentIntentID); - cy.log(response); + if ( + globalState.get("collectShippingDetails") === true || + globalState.get("alwaysCollectShippingDetails") === true + ) { + expect( + response.body.collect_shipping_details_from_wallets, + "collectShippingDetailsFromWallets" + ).to.be.true; + } else + expect( + response.body.collect_shipping_details_from_wallets, + "collectShippingDetailsFromWallets" + ).to.be.false; + globalState.set("paymentID", paymentIntentID); + cy.log(response); + }); }); }); @@ -1275,28 +1432,30 @@ Cypress.Commands.add("createPaymentMethodTest", (globalState, data) => { }).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); - } + cy.wrap(response).then(() => { + 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); + } + }); }); }); @@ -1316,20 +1475,22 @@ Cypress.Commands.add("deletePaymentMethodTest", (globalState) => { 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.payment_method_id).to.equal(paymentMethodId); - expect(response.body.deleted).to.be.true; - } else if (response.status === 500 && baseUrl.includes("localhost")) { - // delete payment method api endpoint requires tartarus (hyperswitch card vault) to be set up since it makes a call to the locker service to delete the payment method - expect(response.body.error.code).to.include("HE_00"); - expect(response.body.error.message).to.include("Something went wrong"); - } else { - throw new Error( - `Payment Method Delete Call Failed with error message: ${response.body.error.message}` - ); - } + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + expect(response.body.payment_method_id).to.equal(paymentMethodId); + expect(response.body.deleted).to.be.true; + } else if (response.status === 500 && baseUrl.includes("localhost")) { + // delete payment method api endpoint requires tartarus (hyperswitch card vault) to be set up since it makes a call to the locker service to delete the payment method + expect(response.body.error.code).to.include("HE_00"); + expect(response.body.error.message).to.include("Something went wrong"); + } else { + throw new Error( + `Payment Method Delete Call Failed with error message: ${response.body.error.message}` + ); + } + }); }); }); @@ -1346,16 +1507,19 @@ Cypress.Commands.add("setDefaultPaymentMethodTest", (globalState) => { 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).to.have.property( - "default_payment_method_id", - payment_method_id - ); - expect(response.body).to.have.property("customer_id", customer_id); - } else { - defaultErrorHandler(response); - } + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + expect(response.body).to.have.property( + "default_payment_method_id", + payment_method_id + ); + expect(response.body).to.have.property("customer_id", customer_id); + } else { + defaultErrorHandler(response); + } + }); }); }); @@ -1397,86 +1561,89 @@ Cypress.Commands.add( body: confirmBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", paymentIntentID); - globalState.set("connectorId", response.body.connector); - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(paymentIntentID, "payment_id").to.equal( - response.body.payment_id - ); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - 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.equal(profileId).and - .to.not.be.null; - - validateErrorMessage(response, resData); - - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("paymentID", paymentIntentID); + globalState.set("connectorId", response.body.connector); + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(paymentIntentID, "payment_id").to.equal( + response.body.payment_id + ); + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + 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.equal(profileId).and + .to.not.be.null; + + validateErrorMessage(response, resData); + + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url ); - } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + 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 resData.body) { + expect(resData.body[key], [key]).to.deep.equal( + response.body[key] + ); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` ); } - } else { - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` - ); - } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url ); - } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + 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 resData.body) { + expect(resData.body[key], [key]).to.deep.equal( + response.body[key] + ); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` ); } } else { throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + `Invalid capture method ${response.body.capture_method}` ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1513,78 +1680,83 @@ Cypress.Commands.add( body: confirmBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(response.headers["content-type"]).to.include("application/json"); - globalState.set("paymentID", paymentIntentId); - globalState.set("connectorId", response.body.connector); - globalState.set("paymentMethodType", confirmBody.payment_method_type); + cy.wrap(response).then(() => { if (response.status === 200) { - validateErrorMessage(response, resData); + expect(response.headers["content-type"]).to.include( + "application/json" + ); + globalState.set("paymentID", paymentIntentId); + globalState.set("connectorId", response.body.connector); + globalState.set("paymentMethodType", confirmBody.payment_method_type); - switch (response.body.authentication_type) { - case "three_ds": - if ( - response.body.capture_method === "automatic" || - response.body.capture_method === "manual" - ) { - if (response.body.status !== "failed") { - // we get many statuses here, hence this verification - if ( - connectorId === "adyen" && - response.body.payment_method_type === "blik" - ) { - expect(response.body) - .to.have.property("next_action") - .to.have.property("type") - .to.equal("wait_screen_information"); - } else { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url + if (response.status === 200) { + validateErrorMessage(response, resData); + + switch (response.body.authentication_type) { + case "three_ds": + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + if (response.body.status !== "failed") { + // we get many statuses here, hence this verification + if ( + connectorId === "adyen" && + response.body.payment_method_type === "blik" + ) { + expect(response.body) + .to.have.property("next_action") + .to.have.property("type") + .to.equal("wait_screen_information"); + } else { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + } + } else if (response.body.status === "failed") { + expect(response.body.error_code).to.equal( + resData.body.error_code ); } - } else if (response.body.status === "failed") { - expect(response.body.error_code).to.equal( - resData.body.error_code + } else { + throw new Error( + `Invalid capture method ${response.body.capture_method}` ); } - } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); - } - break; - case "no_three_ds": - if ( - response.body.capture_method === "automatic" || - response.body.capture_method === "manual" - ) { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - } else { + break; + case "no_three_ds": + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + } else { + throw new Error( + `Invalid capture method ${response.body.capture_method}` + ); + } + break; + default: throw new Error( - `Invalid capture method ${response.body.capture_method}` + `Invalid authentication type ${response.body.authentication_type}` ); - } - break; - default: - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` - ); + } } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1622,53 +1794,56 @@ Cypress.Commands.add( body: confirmBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", paymentIntentID); - validateErrorMessage(response, resData); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("paymentID", paymentIntentID); - if ( - response.body.capture_method === "automatic" || - response.body.capture_method === "manual" - ) { - switch (response.body.payment_method_type) { - case "pix": - expect(response.body) - .to.have.property("next_action") - .to.have.property("qr_code_url"); - if (response.body.next_action.qr_code_url !== null) { - globalState.set( - "nextActionUrl", // This is intentionally kept as nextActionUrl to avoid issues during handleRedirection call, - response.body.next_action.qr_code_url - ); - globalState.set("nextActionType", "qr_code_url"); - } else { + validateErrorMessage(response, resData); + + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + switch (response.body.payment_method_type) { + case "pix": + expect(response.body) + .to.have.property("next_action") + .to.have.property("qr_code_url"); + if (response.body.next_action.qr_code_url !== null) { + globalState.set( + "nextActionUrl", // This is intentionally kept as nextActionUrl to avoid issues during handleRedirection call, + response.body.next_action.qr_code_url + ); + globalState.set("nextActionType", "qr_code_url"); + } else { + globalState.set( + "nextActionUrl", // This is intentionally kept as nextActionUrl to avoid issues during handleRedirection call, + response.body.next_action.image_data_url + ); + globalState.set("nextActionType", "image_data_url"); + } + break; + default: + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); globalState.set( - "nextActionUrl", // This is intentionally kept as nextActionUrl to avoid issues during handleRedirection call, - response.body.next_action.image_data_url + "nextActionUrl", + response.body.next_action.redirect_to_url ); - globalState.set("nextActionType", "image_data_url"); - } - break; - default: - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - break; + break; + } + } else { + throw new Error( + `Invalid capture method ${response.body.capture_method}` + ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1706,39 +1881,42 @@ Cypress.Commands.add( body: confirmBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - validateErrorMessage(response, resData); - if ( - response.body.capture_method === "automatic" || - response.body.capture_method === "manual" - ) { - if (response.body.payment_method_type === "upi_collect") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - } else if (response.body.payment_method_type === "upi_intent") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("qr_code_fetch_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.qr_code_fetch_url + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + validateErrorMessage(response, resData); + + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + if (response.body.payment_method_type === "upi_collect") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + } else if (response.body.payment_method_type === "upi_intent") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("qr_code_fetch_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.qr_code_fetch_url + ); + } + } else { + throw new Error( + `Invalid capture method ${response.body.capture_method}` ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1784,85 +1962,86 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - globalState.set("clientSecret", response.body.client_secret); + cy.wrap(response).then(() => { + globalState.set("clientSecret", response.body.client_secret); + expect(response.headers["content-type"]).to.include("application/json"); - 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); + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(response.body.payment_id, "payment_id").to.equal( + globalState.get("paymentID") + ); + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + expect(response.body.merchant_connector_id, "connector_id").to.equal( + 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.status === 200) { - globalState.set("paymentAmount", createConfirmPaymentBody.amount); - globalState.set("paymentID", response.body.payment_id); - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(response.body.payment_id, "payment_id").to.equal( - globalState.get("paymentID") - ); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - expect(response.body.merchant_connector_id, "connector_id").to.equal( - 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"); - - validateErrorMessage(response, resData); - - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + validateErrorMessage(response, resData); + + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url ); - } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + 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 resData.body) { + expect(resData.body[key], [key]).to.deep.equal( + response.body[key] + ); + } + } else { + throw new Error( + `Invalid authentication type: ${response.body.authentication_type}` ); } - } else { - throw new Error( - `Invalid authentication type: ${response.body.authentication_type}` - ); - } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url ); - } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.deep.equal( - response.body[key] + 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 resData.body) { + expect(resData.body[key], [key]).to.deep.equal( + response.body[key] + ); + } + } else { + throw new Error( + `Invalid authentication type: ${response.body.authentication_type}` ); } - } else { - throw new Error( - `Invalid authentication type: ${response.body.authentication_type}` - ); } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -1906,77 +2085,79 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", paymentIntentID); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("paymentID", paymentIntentID); - globalState.set("paymentID", paymentIntentID); - globalState.set("connectorId", response.body.connector); - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(paymentIntentID, "payment_id").to.equal( - response.body.payment_id - ); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - expect(merchant_connector_id, "connector_id").to.equal( - response.body.merchant_connector_id - ); - expect(response.body.customer, "customer").to.not.be.empty; - 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; - expect(response.body.payment_token, "payment_token").to.not.be.null; - - validateErrorMessage(response, resData); - - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - } else if (response.body.authentication_type === "no_three_ds") { - 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") - ); - } else { - // Handle other authentication types as needed - throw new Error( - `Invalid authentication type: ${response.body.authentication_type}` - ); + globalState.set("paymentID", paymentIntentID); + globalState.set("connectorId", response.body.connector); + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(paymentIntentID, "payment_id").to.equal( + response.body.payment_id + ); + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + expect(merchant_connector_id, "connector_id").to.equal( + response.body.merchant_connector_id + ); + expect(response.body.customer, "customer").to.not.be.empty; + if (reqData.billing !== null) { + expect(response.body.billing, "billing_address").to.not.be.empty; } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + expect(response.body.profile_id, "profile_id").to.not.be.null; + expect(response.body.payment_token, "payment_token").to.not.be.null; + + validateErrorMessage(response, resData); + + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + } else if (response.body.authentication_type === "no_three_ds") { + 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") + ); + } else { + // Handle other authentication types as needed + throw new Error( + `Invalid authentication type: ${response.body.authentication_type}` + ); + } + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + } else if (response.body.authentication_type === "no_three_ds") { + 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") + ); + } else { + // Handle other authentication types as needed + throw new Error( + `Invalid authentication type: ${response.body.authentication_type}` + ); } - expect(response.body.customer_id).to.equal( - globalState.get("customerId") - ); } else { - // Handle other authentication types as needed + // Handle other capture methods as needed throw new Error( - `Invalid authentication type: ${response.body.authentication_type}` + `Invalid capture method: ${response.body.capture_method}` ); } } else { - // Handle other capture methods as needed - throw new Error( - `Invalid capture method: ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2005,15 +2186,17 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - 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 resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + cy.wrap(response).then(() => { + 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 resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2039,14 +2222,16 @@ Cypress.Commands.add("voidCallTest", (requestBody, data, globalState) => { }).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]); + cy.wrap(response).then(() => { + 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); } - } else { - defaultErrorHandler(response, resData); - } + }); }); }); @@ -2072,55 +2257,57 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.payment_id).to.equal(payment_id); - expect(response.body.amount).to.equal(globalState.get("paymentAmount")); - expect(response.body.profile_id, "profile_id").to.not.be.null; - expect(response.body.billing, "billing_address").to.not.be.empty; - expect(response.body.customer, "customer").to.not.be.empty; - if ( - ["succeeded", "processing", "requires_customer_action"].includes( - response.body.status - ) - ) { - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - expect(response.body.payment_method, "payment_method").to.not.be.null; - expect(response.body.merchant_connector_id, "connector_id").to.equal( - merchant_connector_id - ); - } + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.payment_id).to.equal(payment_id); + expect(response.body.amount).to.equal(globalState.get("paymentAmount")); + expect(response.body.profile_id, "profile_id").to.not.be.null; + expect(response.body.billing, "billing_address").to.not.be.empty; + expect(response.body.customer, "customer").to.not.be.empty; + if ( + ["succeeded", "processing", "requires_customer_action"].includes( + response.body.status + ) + ) { + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + expect(response.body.payment_method, "payment_method").to.not.be.null; + expect(response.body.merchant_connector_id, "connector_id").to.equal( + merchant_connector_id + ); + } - if (autoretries) { - expect(response.body).to.have.property("attempts"); - expect(response.body.attempts).to.be.an("array").and.not.empty; - expect(response.body.attempts.length).to.equal(attempt); - expect(response.body.attempts[0].attempt_id).to.include( - `${payment_id}_` - ); - for (const key in response.body.attempts) { - if ( - response.body.attempts[key].attempt_id === - `${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}` && - response.body.status === "requires_customer_action" - ) { - expect(response.body.attempts[key].status).to.equal( - "authentication_pending" - ); - } else { - expect(response.body.attempts[key].status).to.equal("failure"); + if (autoretries) { + expect(response.body).to.have.property("attempts"); + expect(response.body.attempts).to.be.an("array").and.not.empty; + expect(response.body.attempts.length).to.equal(attempt); + expect(response.body.attempts[0].attempt_id).to.include( + `${payment_id}_` + ); + for (const key in response.body.attempts) { + if ( + response.body.attempts[key].attempt_id === + `${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}` && + response.body.status === "requires_customer_action" + ) { + expect(response.body.attempts[key].status).to.equal( + "authentication_pending" + ); + } else { + expect(response.body.attempts[key].status).to.equal("failure"); + } } } - } + }); }); } ); @@ -2149,17 +2336,19 @@ Cypress.Commands.add( body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("refundId", response.body.refund_id); - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("refundId", response.body.refund_id); + 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, resData); } - expect(response.body.payment_id).to.equal(payment_id); - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2180,10 +2369,12 @@ Cypress.Commands.add("syncRefundCallTest", (data, globalState) => { }).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]); - } + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + }); }); }); @@ -2233,88 +2424,91 @@ Cypress.Commands.add( body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", response.body.payment_id); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(merchant_connector_id, "connector_id").to.equal( - response.body.merchant_connector_id - ); - expect(response.body.customer, "customer").to.not.be.empty; - expect(response.body.profile_id, "profile_id").to.not.be.null; - if (response.body.status !== "failed") { - expect(response.body.payment_method_id, "payment_method_id").to.not.be - .null; - } + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("paymentID", response.body.payment_id); - if (requestBody.mandate_data === null) { - expect(response.body).to.have.property("payment_method_id"); - globalState.set("paymentMethodId", response.body.payment_method_id); - } else { - expect(response.body).to.have.property("mandate_id"); - globalState.set("mandateId", response.body.mandate_id); - } + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(merchant_connector_id, "connector_id").to.equal( + response.body.merchant_connector_id + ); + expect(response.body.customer, "customer").to.not.be.empty; + expect(response.body.profile_id, "profile_id").to.not.be.null; + if (response.body.status !== "failed") { + expect(response.body.payment_method_id, "payment_method_id").to.not + .be.null; + } - if (response.body.capture_method === "automatic") { - expect(response.body).to.have.property("mandate_id"); - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - cy.log(nextActionUrl); - 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 resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); - } + if (requestBody.mandate_data === null) { + expect(response.body).to.have.property("payment_method_id"); + globalState.set("paymentMethodId", response.body.payment_method_id); } else { - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` - ); + expect(response.body).to.have.property("mandate_id"); + globalState.set("mandateId", response.body.mandate_id); } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - globalState.set( - "nextActionUrl", - response.body.next_action.redirect_to_url - ); - cy.log(nextActionUrl); - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + + if (response.body.capture_method === "automatic") { + expect(response.body).to.have.property("mandate_id"); + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } } else { throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + `Invalid capture method ${response.body.capture_method}` ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2357,77 +2551,80 @@ Cypress.Commands.add( body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", response.body.payment_id); - expect(response.body.payment_method_data, "payment_method_data").to.not - .be.empty; - expect(response.body.connector, "connector").to.equal( - globalState.get("connectorId") - ); - expect(merchant_connector_id, "connector_id").to.equal( - response.body.merchant_connector_id - ); - expect(response.body.customer, "customer").to.not.be.empty; - expect(response.body.profile_id, "profile_id").to.not.be.null; - expect(response.body.payment_method_id, "payment_method_id").to.not.be - .null; - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("paymentID", response.body.payment_id); + expect(response.body.payment_method_data, "payment_method_data").to + .not.be.empty; + expect(response.body.connector, "connector").to.equal( + globalState.get("connectorId") + ); + expect(merchant_connector_id, "connector_id").to.equal( + response.body.merchant_connector_id + ); + expect(response.body.customer, "customer").to.not.be.empty; + expect(response.body.profile_id, "profile_id").to.not.be.null; + expect(response.body.payment_method_id, "payment_method_id").to.not.be + .null; + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } } else { throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + `Invalid capture method ${response.body.capture_method}` ); } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - 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 resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); - } - } else { - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + } else if (response.status === 400) { + if (response.body.error.message === "Mandate Validation Failed") { + expect(response.body.error.code).to.equal("HE_03"); + expect(response.body.error.message).to.equal( + "Mandate Validation Failed" + ); + expect(response.body.error.reason).to.equal( + "request amount is greater than mandate amount" ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else if (response.status === 400) { - if (response.body.error.message === "Mandate Validation Failed") { - expect(response.body.error.code).to.equal("HE_03"); - expect(response.body.error.message).to.equal( - "Mandate Validation Failed" - ); - expect(response.body.error.reason).to.equal( - "request amount is greater than mandate amount" - ); - } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2472,69 +2669,73 @@ Cypress.Commands.add( body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("paymentID", response.body.payment_id); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.payment_method_id, "payment_method_id").to.include( - "pm_" - ).and.to.not.be.null; - expect( - response.body.connector_transaction_id, - "connector_transaction_id" - ).to.not.be.null; - expect( - response.body.payment_method_status, - "payment_method_status" - ).to.equal("active"); - - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - 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 resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); - } - } else { - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` - ); - } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + if (response.status === 200) { + globalState.set("paymentID", response.body.payment_id); + + expect( + response.body.payment_method_id, + "payment_method_id" + ).to.include("pm_").and.to.not.be.null; + expect( + response.body.connector_transaction_id, + "connector_transaction_id" + ).to.not.be.null; + expect( + response.body.payment_method_status, + "payment_method_status" + ).to.equal("active"); + + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } } else { throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + `Invalid capture method ${response.body.capture_method}` ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2575,57 +2776,61 @@ Cypress.Commands.add( }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(response.headers["content-type"]).to.include("application/json"); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.headers["content-type"]).to.include( + "application/json" + ); - globalState.set("paymentID", response.body.payment_id); - - if (response.body.capture_method === "automatic") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - 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 resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); - } - } else { - throw new Error( - `Invalid authentication type ${response.body.authentication_type}` - ); - } - } else if (response.body.capture_method === "manual") { - if (response.body.authentication_type === "three_ds") { - expect(response.body) - .to.have.property("next_action") - .to.have.property("redirect_to_url"); - const nextActionUrl = response.body.next_action.redirect_to_url; - cy.log(nextActionUrl); - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + globalState.set("paymentID", response.body.payment_id); + + if (response.body.capture_method === "automatic") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } - } else if (response.body.authentication_type === "no_three_ds") { - for (const key in resData.body) { - expect(resData.body[key], [key]).to.equal(response.body[key]); + } else if (response.body.capture_method === "manual") { + if (response.body.authentication_type === "three_ds") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + const nextActionUrl = response.body.next_action.redirect_to_url; + cy.log(nextActionUrl); + 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 resData.body) { + expect(resData.body[key], [key]).to.equal(response.body[key]); + } + } else { + throw new Error( + `Invalid authentication type ${response.body.authentication_type}` + ); } } else { throw new Error( - `Invalid authentication type ${response.body.authentication_type}` + `Invalid capture method ${response.body.capture_method}` ); } } else { - throw new Error( - `Invalid capture method ${response.body.capture_method}` - ); + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2642,14 +2847,15 @@ Cypress.Commands.add("listMandateCallTest", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - - let i = 0; - for (i in response.body) { - if (response.body[i].mandate_id === globalState.get("mandateId")) { - expect(response.body[i].status).to.equal("active"); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + let i = 0; + for (i in response.body) { + if (response.body[i].mandate_id === globalState.get("mandateId")) { + expect(response.body[i].status).to.equal("active"); + } } - } + }); }); }); @@ -2666,12 +2872,16 @@ Cypress.Commands.add("revokeMandateCallTest", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.body.status === 200) { - expect(response.body.status).to.equal("revoked"); - } else if (response.body.status === 400) { - expect(response.body.reason).to.equal("Mandate has already been revoked"); - } + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.body.status === 200) { + expect(response.body.status).to.equal("revoked"); + } else if (response.body.status === 400) { + expect(response.body.reason).to.equal( + "Mandate has already been revoked" + ); + } + }); }); }); @@ -2758,39 +2968,42 @@ Cypress.Commands.add("listCustomerPMCallTest", (globalState) => { }, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.body.customer_payment_methods[0]?.payment_token) { - const paymentToken = - response.body.customer_payment_methods[0].payment_token; - const paymentMethodId = - response.body.customer_payment_methods[0].payment_method_id; - globalState.set("paymentToken", paymentToken); // Set paymentToken in globalState - globalState.set("paymentMethodId", paymentMethodId); // Set paymentMethodId in globalState - } else { - // We only get an empty array if something's wrong. One exception is a 4xx when no customer exist but it is handled in the test - expect(response.body) - .to.have.property("customer_payment_methods") - .to.be.an("array").and.empty; - } - expect(globalState.get("customerId"), "customer_id").to.equal( - response.body.customer_payment_methods[0].customer_id - ); - expect( - response.body.customer_payment_methods[0].payment_token, - "payment_token" - ).to.not.be.null; - expect( - response.body.customer_payment_methods[0].payment_method_id, - "payment_method_id" - ).to.not.be.null; - expect( - response.body.customer_payment_methods[0].payment_method, - "payment_method" - ).to.not.be.null; - expect( - response.body.customer_payment_methods[0].payment_method_type, - "payment_method_type" - ).to.not.be.null; + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.body.customer_payment_methods[0]?.payment_token) { + const paymentToken = + response.body.customer_payment_methods[0].payment_token; + const paymentMethodId = + response.body.customer_payment_methods[0].payment_method_id; + globalState.set("paymentToken", paymentToken); // Set paymentToken in globalState + globalState.set("paymentMethodId", paymentMethodId); // Set paymentMethodId in globalState + } else { + // We only get an empty array if something's wrong. One exception is a 4xx when no customer exist but it is handled in the test + expect(response.body) + .to.have.property("customer_payment_methods") + .to.be.an("array").and.empty; + } + expect(globalState.get("customerId"), "customer_id").to.equal( + response.body.customer_payment_methods[0].customer_id + ); + expect( + response.body.customer_payment_methods[0].payment_token, + "payment_token" + ).to.not.be.null; + expect( + response.body.customer_payment_methods[0].payment_method_id, + "payment_method_id" + ).to.not.be.null; + expect( + response.body.customer_payment_methods[0].payment_method, + "payment_method" + ).to.not.be.null; + expect( + response.body.customer_payment_methods[0].payment_method_type, + "payment_method_type" + ).to.not.be.null; + }); }); }); @@ -2806,24 +3019,27 @@ Cypress.Commands.add("listCustomerPMByClientSecret", (globalState) => { }, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.body.customer_payment_methods[0]?.payment_token) { - const paymentToken = - response.body.customer_payment_methods[0].payment_token; - const paymentMethodId = - response.body.customer_payment_methods[0].payment_method_id; - globalState.set("paymentToken", paymentToken); - globalState.set("paymentMethodId", paymentMethodId); - expect( - response.body.customer_payment_methods[0].payment_method_id, - "payment_method_id" - ).to.not.be.null; - } else { - // We only get an empty array if something's wrong. One exception is a 4xx when no customer exist but it is handled in the test - expect(response.body) - .to.have.property("customer_payment_methods") - .to.be.an("array").and.empty; - } + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.body.customer_payment_methods[0]?.payment_token) { + const paymentToken = + response.body.customer_payment_methods[0].payment_token; + const paymentMethodId = + response.body.customer_payment_methods[0].payment_method_id; + globalState.set("paymentToken", paymentToken); + globalState.set("paymentMethodId", paymentMethodId); + expect( + response.body.customer_payment_methods[0].payment_method_id, + "payment_method_id" + ).to.not.be.null; + } else { + // We only get an empty array if something's wrong. One exception is a 4xx when no customer exist but it is handled in the test + expect(response.body) + .to.have.property("customer_payment_methods") + .to.be.an("array").and.empty; + } + }); }); }); @@ -2838,8 +3054,11 @@ Cypress.Commands.add("listRefundCallTest", (requestBody, globalState) => { body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.data).to.be.an("array").and.not.empty; + + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.data).to.be.an("array").and.not.empty; + }); }); }); @@ -2866,17 +3085,19 @@ Cypress.Commands.add( body: createConfirmPayoutBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("payoutAmount", createConfirmPayoutBody.amount); - globalState.set("payoutID", response.body.payout_id); - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + if (response.status === 200) { + globalState.set("payoutAmount", createConfirmPayoutBody.amount); + globalState.set("payoutID", response.body.payout_id); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2905,17 +3126,20 @@ Cypress.Commands.add( body: createConfirmPayoutBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - globalState.set("payoutAmount", createConfirmPayoutBody.amount); - globalState.set("payoutID", response.body.payout_id); - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + + if (response.status === 200) { + globalState.set("payoutAmount", createConfirmPayoutBody.amount); + globalState.set("payoutID", response.body.payout_id); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2938,15 +3162,18 @@ Cypress.Commands.add( body: payoutFulfillBody, }).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]); + cy.wrap(response).then(() => { + 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); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2970,15 +3197,18 @@ Cypress.Commands.add( body: payoutConfirmBody, }).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]); + cy.wrap(response).then(() => { + 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); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -2996,9 +3226,11 @@ Cypress.Commands.add("retrievePayoutCallTest", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - expect(response.body.payout_id).to.equal(payout_id); - expect(response.body.amount).to.equal(globalState.get("payoutAmount")); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + expect(response.body.payout_id).to.equal(payout_id); + expect(response.body.amount).to.equal(globalState.get("payoutAmount")); + }); }); }); @@ -3024,19 +3256,24 @@ Cypress.Commands.add("userLogin", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - if (response.body.token_type === "totp") { - expect(response.body, "totp_token").to.have.property("token").and.to.not - .be.empty; + cy.wrap(response).then(() => { + if (response.status === 200) { + if (response.body.token_type === "totp") { + expect(response.body, "totp_token").to.have.property("token").and.to + .not.be.empty; - const totpToken = response.body.token; - globalState.set("totpToken", totpToken); + const totpToken = response.body.token; + if (!totpToken) { + throw new Error("No token received from login"); + } + globalState.set("totpToken", totpToken); + } + } else { + throw new Error( + `User login call failed to get totp token with status: "${response.status}" and message: "${response.body.error.message}"` + ); } - } else { - throw new Error( - `User login call failed to get totp token with status: "${response.status}" and message: "${response.body.error.message}"` - ); - } + }); }); }); Cypress.Commands.add("terminate2Fa", (globalState) => { @@ -3057,56 +3294,67 @@ Cypress.Commands.add("terminate2Fa", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - if (response.body.token_type === "user_info") { - expect(response.body, "user_info_token").to.have.property("token").and - .to.not.be.empty; + cy.wrap(response).then(() => { + if (response.status === 200) { + if (response.body.token_type === "user_info") { + expect(response.body, "user_info_token").to.have.property("token").and + .to.not.be.empty; - const userInfoToken = response.body.token; - globalState.set("userInfoToken", userInfoToken); + const userInfoToken = response.body.token; + if (!userInfoToken) { + throw new Error("No user info token received"); + } + globalState.set("userInfoToken", userInfoToken); + } + } else { + throw new Error( + `2FA terminate call failed with status: "${response.status}" and message: "${response.body.error.message}"` + ); } - } else { - throw new Error( - `2FA terminate call failed with status: "${response.status}" and message: "${response.body.error.message}"` - ); - } + }); }); }); Cypress.Commands.add("userInfo", (globalState) => { // Define the necessary variables and constant const baseUrl = globalState.get("baseUrl"); - const apiKey = globalState.get("userInfoToken"); + const userInfoToken = globalState.get("userInfoToken"); const url = `${baseUrl}/user`; + if (!userInfoToken) { + throw new Error("No user info token available"); + } + cy.request({ method: "GET", url: url, headers: { - Authorization: `Bearer ${apiKey}`, + Authorization: `Bearer ${userInfoToken}`, "Content-Type": "application/json", }, failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(response.body, "merchant_id").to.have.property("merchant_id").and - .to.not.be.empty; - expect(response.body, "organization_id").to.have.property("org_id").and.to - .not.be.empty; - expect(response.body, "profile_id").to.have.property("profile_id").and.to - .not.be.empty; + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body, "merchant_id").to.have.property("merchant_id").and + .to.not.be.empty; + expect(response.body, "organization_id").to.have.property("org_id").and + .to.not.be.empty; + expect(response.body, "profile_id").to.have.property("profile_id").and + .to.not.be.empty; - globalState.set("merchantId", response.body.merchant_id); - globalState.set("organizationId", response.body.org_id); - globalState.set("profileId", response.body.profile_id); + globalState.set("merchantId", response.body.merchant_id); + globalState.set("organizationId", response.body.org_id); + globalState.set("profileId", response.body.profile_id); - globalState.set("userInfoToken", apiKey); - } else { - throw new Error( - `User login call failed to fetch user info with status: "${response.status}" and message: "${response.body.error.message}"` - ); - } + globalState.set("userInfoToken", userInfoToken); + } else { + throw new Error( + `User login call failed to fetch user info with status: "${response.status}" and message: "${response.body.error.message}"` + ); + } + }); }); }); @@ -3125,11 +3373,13 @@ Cypress.Commands.add("ListMcaByMid", (globalState) => { }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - globalState.set("profileId", response.body[0].profile_id); - globalState.set("stripeMcaId", response.body[0].merchant_connector_id); - globalState.set("adyenMcaId", response.body[1].merchant_connector_id); - globalState.set("bluesnapMcaId", response.body[3].merchant_connector_id); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + globalState.set("profileId", response.body[0].profile_id); + globalState.set("stripeMcaId", response.body[0].merchant_connector_id); + globalState.set("adyenMcaId", response.body[1].merchant_connector_id); + globalState.set("bluesnapMcaId", response.body[3].merchant_connector_id); + }); }); }); @@ -3157,17 +3407,20 @@ Cypress.Commands.add( body: routingBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.headers["content-type"]).to.include("application/json"); - if (response.status === 200) { - expect(response.body).to.have.property("id"); - globalState.set("routingConfigId", response.body.id); - for (const key in resData.body) { - expect(resData.body[key]).to.equal(response.body[key]); + cy.wrap(response).then(() => { + expect(response.headers["content-type"]).to.include("application/json"); + + if (response.status === 200) { + expect(response.body).to.have.property("id"); + globalState.set("routingConfigId", response.body.id); + for (const key in resData.body) { + expect(resData.body[key]).to.equal(response.body[key]); + } + } else { + defaultErrorHandler(response, resData); } - } else { - defaultErrorHandler(response, resData); - } + }); }); } ); @@ -3186,16 +3439,19 @@ Cypress.Commands.add("activateRoutingConfig", (data, globalState) => { 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]); + cy.wrap(response).then(() => { + 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); } - } else { - defaultErrorHandler(response, resData); - } + }); }); }); @@ -3213,16 +3469,19 @@ Cypress.Commands.add("retrieveRoutingConfig", (data, globalState) => { 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]); + cy.wrap(response).then(() => { + 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); } - } else { - defaultErrorHandler(response, resData); - } + }); }); }); @@ -3241,69 +3500,24 @@ Cypress.Commands.add( failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - if (response.status === 200) { - expect(response.body) - .to.have.property("message") - .to.equal("card_declined"); - expect(response.body).to.have.property("connector").to.equal("stripe"); - expect(response.body) - .to.have.property("step_up_possible") - .to.equal(step_up_possible); - } + + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body) + .to.have.property("message") + .to.equal("card_declined"); + expect(response.body) + .to.have.property("connector") + .to.equal("stripe"); + expect(response.body) + .to.have.property("step_up_possible") + .to.equal(step_up_possible); + } + }); }); } ); -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}"` - ); - } - - 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); - } - }); -}); - Cypress.Commands.add("incrementalAuth", (globalState, data) => { const { Request: reqData, Response: resData } = data || {}; @@ -3324,140 +3538,103 @@ Cypress.Commands.add("incrementalAuth", (globalState, data) => { }).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; + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body.amount_capturable, "amount_capturable").to.equal( + resData.body.amount_capturable + ); expect( - response.body.incremental_authorizations[key], - "error_code" - ).to.have.property("error_code").to.be.null; + response.body.authorization_count, + "authorization_count" + ).to.be.a("number").and.not.be.null; expect( - response.body.incremental_authorizations[key], - "error_message" - ).to.have.property("error_message").to.be.null; + response.body.incremental_authorization_allowed, + "incremental_authorization_allowed" + ).to.be.true; 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"); + 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"); + } } - } - }); -}); - -Cypress.Commands.add("createConfigs", (globalState, key, value) => { - const base_url = globalState.get("baseUrl"); - const api_key = globalState.get("adminApiKey"); - - cy.request({ - method: "POST", - url: `${base_url}/configs/`, - headers: { - "Content-Type": "application/json", - "api-key": api_key, - }, - body: { - key: key, - value: value, - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); - - expect(response.status).to.equal(200); - expect(response.body).to.have.property("key").to.equal(key); - expect(response.body).to.have.property("value").to.equal(value); + }); }); }); -Cypress.Commands.add("fetchConfigs", (globalState, key, value) => { - const base_url = globalState.get("baseUrl"); - const api_key = globalState.get("adminApiKey"); - - cy.request({ - method: "GET", - url: `${base_url}/configs/${key}`, - headers: { - "Content-Type": "application/json", - "api-key": api_key, - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); - - expect(response.status).to.equal(200); - expect(response.body).to.have.property("key").to.equal(key); - expect(response.body).to.have.property("value").to.equal(value); - }); -}); +Cypress.Commands.add("setConfigs", (globalState, key, value, requestType) => { + if (!key || !requestType) { + throw new Error("Key and requestType are required parameters"); + } -Cypress.Commands.add("updateConfigs", (globalState, key, value) => { - const base_url = globalState.get("baseUrl"); - const api_key = globalState.get("adminApiKey"); + const REQUEST_CONFIG = { + CREATE: { method: "POST", useKey: false }, + UPDATE: { method: "POST", useKey: true }, + FETCH: { method: "GET", useKey: true }, + DELETE: { method: "DELETE", useKey: true }, + }; - cy.request({ - method: "POST", - url: `${base_url}/configs/${key}`, - headers: { - "Content-Type": "application/json", - "api-key": api_key, - }, - body: { - key: key, - value: value, - }, - failOnStatusCode: false, - }).then((response) => { - logRequestId(response.headers["x-request-id"]); + const config = REQUEST_CONFIG[requestType]; + if (!config) { + throw new Error(`Invalid requestType: ${requestType}`); + } - expect(response.status).to.equal(200); - expect(response.body).to.have.property("key").to.equal(key); - expect(response.body).to.have.property("value").to.equal(value); - }); -}); + const apiKey = globalState.get("adminApiKey"); + const baseUrl = globalState.get("baseUrl"); + const url = `${baseUrl}/configs/${config.useKey ? key : ""}`; -Cypress.Commands.add("deleteConfigs", (globalState, key, value) => { - const base_url = globalState.get("baseUrl"); - const api_key = globalState.get("adminApiKey"); + const getRequestBody = { + CREATE: () => ({ key, value }), + UPDATE: () => ({ value }), + }; + const body = getRequestBody[requestType]?.() || undefined; cy.request({ - method: "DELETE", - url: `${base_url}/configs/${key}`, + method: config.method, + url, headers: { "Content-Type": "application/json", - "api-key": api_key, + "api-key": apiKey, }, + ...(body && { body }), failOnStatusCode: false, }).then((response) => { logRequestId(response.headers["x-request-id"]); - expect(response.status).to.equal(200); - expect(response.body).to.have.property("key").to.equal(key); - expect(response.body).to.have.property("value").to.equal(value); + cy.wrap(response).then(() => { + if (response.status === 200) { + expect(response.body).to.have.property("key").to.equal(key); + expect(response.body).to.have.property("value").to.equal(value); + } else { + throw new Error( + `Failed to set configs with status ${response.status} and message ${response.body.error.message}` + ); + } + }); }); }); diff --git a/cypress-tests/cypress/support/e2e.js b/cypress-tests/cypress/support/e2e.js index 7013dc8ddc0..eab7b99b629 100644 --- a/cypress-tests/cypress/support/e2e.js +++ b/cypress-tests/cypress/support/e2e.js @@ -17,11 +17,14 @@ import "cypress-mochawesome-reporter/register"; import "./commands"; -// Alternatively you can use CommonJS syntax: -// require('./commands') +// Add error handling for dynamic imports +Cypress.on("uncaught:exception", (err, runnable) => { + // Log the error details + // eslint-disable-next-line no-console + console.log( + `Error: ${err.message}\nError occurred in: ${runnable.title}\nStack trace: ${err.stack}` + ); -Cypress.on("uncaught:exception", (err) => { - // returning false here prevents Cypress from failing the test - cy.log(`Unhandled exception: ${err}`); + // Return false to prevent the error from failing the test return false; }); diff --git a/cypress-tests/cypress/support/redirectionHandler.js b/cypress-tests/cypress/support/redirectionHandler.js index 2cfa8a1f72b..cc9c180b35e 100644 --- a/cypress-tests/cypress/support/redirectionHandler.js +++ b/cypress-tests/cypress/support/redirectionHandler.js @@ -272,143 +272,150 @@ function bankRedirectRedirection( } cy.then(() => { - try { - verifyReturnUrl(redirection_url, expected_url, verifyUrl); - } catch (error) { - cy.log("Error during return URL verification:", error); - throw error; - } + verifyReturnUrl(redirection_url, expected_url, verifyUrl); }); } function threeDsRedirection(redirection_url, expected_url, connectorId) { cy.visit(redirection_url.href); - if (connectorId === "adyen") { - cy.get("iframe") - .its("0.contentDocument.body") - .within(() => { - cy.get('input[type="password"]').click(); - cy.get('input[type="password"]').type("password"); - cy.get("#buttonSubmit").click(); - }); - } else if (connectorId === "bankofamerica" || connectorId === "wellsfargo") { - // Wait for iframe to be present and visible - cy.get("iframe", { timeout: TIMEOUT }) - .should("be.visible") - .its("0.contentDocument.body") - .should("not.be.empty") // Ensure body has content - .within(() => { - // Add retry ability and multiple selector attempts - cy.get( - 'input[type="text"], input[type="password"], input[name="challengeDataEntry"]', - { timeout: TIMEOUT } - ) - .should("be.visible") - .should("be.enabled") - .click() - .type("1234"); - - cy.get('input[value="SUBMIT"], button[type="submit"]', { - timeout: TIMEOUT, - }) - .should("be.visible") - .click(); - }); - } else if (connectorId === "cybersource") { - cy.url({ timeout: TIMEOUT }).should("include", expected_url.origin); - return; // this is mandatory, else refunds section will fail with unhandled promise rejections even though it is handled - } else if (connectorId === "checkout") { - cy.get("iframe", { timeout: TIMEOUT }) - .its("0.contentDocument.body") - .within(() => { - cy.get('form[id="form"]', { timeout: WAIT_TIME }) - .should("exist") - .then(() => { - cy.get('input[id="password"]').click(); - cy.get('input[id="password"]').type("Checkout1!"); - cy.get("#txtButton").click(); - }); - }); - } else if ( - connectorId === "nmi" || - connectorId === "noon" || - connectorId == "xendit" - ) { - cy.get("iframe", { timeout: TIMEOUT }) - .its("0.contentDocument.body") - .within(() => { - cy.get("iframe", { timeout: TIMEOUT }) - .its("0.contentDocument.body") - .within(() => { - cy.get('form[name="cardholderInput"]', { timeout: TIMEOUT }) - .should("exist") - .then(() => { - cy.get('input[name="challengeDataEntry"]').click().type("1234"); - cy.get('input[value="SUBMIT"]').click(); - }); - }); - }); - } else if (connectorId === "novalnet") { - cy.get("form", { timeout: WAIT_TIME }) - .should("exist") - .then(() => { - cy.get('input[id="submit"]').click(); - }); - } else if (connectorId === "stripe") { - cy.get("iframe", { timeout: TIMEOUT }) - .its("0.contentDocument.body") - .within(() => { - cy.get("iframe") - .its("0.contentDocument.body") - .within(() => { - cy.get("#test-source-authorize-3ds").click(); - }); - }); - } else if (connectorId === "trustpay") { - cy.get('form[name="challengeForm"]', { timeout: WAIT_TIME }) - .should("exist") - .then(() => { - cy.get("#outcomeSelect").select("Approve").should("have.value", "Y"); - cy.get('button[type="submit"]').click(); - }); - } else if (connectorId === "worldpay") { - cy.get("iframe", { timeout: WAIT_TIME }) - .its("0.contentDocument.body") - .within(() => { - cy.get('form[name="cardholderInput"]', { timeout: WAIT_TIME }) - .should("exist") - .then(() => { - cy.get('input[name="challengeDataEntry"]').click().type("1234"); - cy.get('input[value="SUBMIT"]').click(); - }); - }); - } else if (connectorId === "fiuu") { - cy.get('form[id="cc_form"]', { timeout: TIMEOUT }) - .should("exist") - .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(); - }); - }); - } else { - // If connectorId is neither of adyen, trustpay, nmi, stripe, bankofamerica or cybersource, wait for 10 seconds - cy.wait(WAIT_TIME); + switch (connectorId) { + case "adyen": + cy.get("iframe") + .its("0.contentDocument.body") + .within(() => { + cy.get('input[type="password"]').click(); + cy.get('input[type="password"]').type("password"); + cy.get("#buttonSubmit").click(); + }); + break; + + case "bankofamerica": + case "wellsfargo": + cy.get("iframe", { timeout: TIMEOUT }) + .should("be.visible") + .its("0.contentDocument.body") + .should("not.be.empty") + .within(() => { + cy.get( + 'input[type="text"], input[type="password"], input[name="challengeDataEntry"]', + { timeout: TIMEOUT } + ) + .should("be.visible") + .should("be.enabled") + .click() + .type("1234"); + + cy.get('input[value="SUBMIT"], button[type="submit"]', { + timeout: TIMEOUT, + }) + .should("be.visible") + .click(); + }); + break; + + case "cybersource": + cy.url({ timeout: TIMEOUT }).should("include", expected_url.origin); + break; + + case "checkout": + cy.get("iframe", { timeout: TIMEOUT }) + .its("0.contentDocument.body") + .within(() => { + cy.get('form[id="form"]', { timeout: WAIT_TIME }) + .should("exist") + .then(() => { + cy.get('input[id="password"]').click(); + cy.get('input[id="password"]').type("Checkout1!"); + cy.get("#txtButton").click(); + }); + }); + break; + + case "nmi": + case "noon": + case "xendit": + cy.get("iframe", { timeout: TIMEOUT }) + .its("0.contentDocument.body") + .within(() => { + cy.get("iframe", { timeout: TIMEOUT }) + .its("0.contentDocument.body") + .within(() => { + cy.get('form[name="cardholderInput"]', { timeout: TIMEOUT }) + .should("exist") + .then(() => { + cy.get('input[name="challengeDataEntry"]') + .click() + .type("1234"); + cy.get('input[value="SUBMIT"]').click(); + }); + }); + }); + break; + + case "novalnet": + cy.get("form", { timeout: WAIT_TIME }) + .should("exist") + .then(() => { + cy.get('input[id="submit"]').click(); + }); + break; + + case "stripe": + cy.get("iframe", { timeout: TIMEOUT }) + .its("0.contentDocument.body") + .within(() => { + cy.get("iframe") + .its("0.contentDocument.body") + .within(() => { + cy.get("#test-source-authorize-3ds").click(); + }); + }); + break; + + case "trustpay": + cy.get('form[name="challengeForm"]', { timeout: WAIT_TIME }) + .should("exist") + .then(() => { + cy.get("#outcomeSelect").select("Approve").should("have.value", "Y"); + cy.get('button[type="submit"]').click(); + }); + break; + + case "worldpay": + cy.get("iframe", { timeout: WAIT_TIME }) + .its("0.contentDocument.body") + .within(() => { + cy.get('form[name="cardholderInput"]', { timeout: WAIT_TIME }) + .should("exist") + .then(() => { + cy.get('input[name="challengeDataEntry"]').click().type("1234"); + cy.get('input[value="SUBMIT"]').click(); + }); + }); + break; + + case "fiuu": + cy.get('form[id="cc_form"]', { timeout: TIMEOUT }) + .should("exist") + .then(() => { + cy.get('button.pay-btn[name="pay"]').click(); + cy.get("div.otp") + .invoke("text") + .then((otpText) => { + const otp = otpText.match(/\d+/)[0]; + cy.get("input#otp-input").should("not.be.disabled").type(otp); + cy.get("button.pay-btn").click(); + }); + }); + break; + + default: + cy.wait(WAIT_TIME); } - cy.then(() => { - try { - verifyReturnUrl(redirection_url, expected_url, true); - } catch (error) { - cy.log("Error during return URL verification:", error); - throw error; - } - }); + // Verify return URL after handling the specific connector + verifyReturnUrl(redirection_url, expected_url, true); } function upiRedirection( @@ -448,17 +455,14 @@ function upiRedirection( } cy.then(() => { - try { - verifyReturnUrl(redirection_url, expected_url, verifyUrl); - } catch (error) { - cy.log("Error during return URL verification:", error); - throw error; - } + verifyReturnUrl(redirection_url, expected_url, verifyUrl); }); } function verifyReturnUrl(redirection_url, expected_url, forward_flow) { - if (forward_flow) { + if (!forward_flow) return; + + try { if (redirection_url.host.endsWith(expected_url.host)) { cy.wait(WAIT_TIME / 2); @@ -470,7 +474,6 @@ function verifyReturnUrl(redirection_url, expected_url, forward_flow) { // For blank page cy.wrap(doc.body.innerText.trim()).then((text) => { if (text === "") { - // Assert before screenshot cy.wrap(text).should("eq", ""); cy.screenshot("blank-page-error"); } @@ -488,7 +491,6 @@ function verifyReturnUrl(redirection_url, expected_url, forward_flow) { const pageText = doc.body.innerText.toLowerCase(); cy.wrap(pageText).then((text) => { if (errorPatterns.some((pattern) => pattern.test(text))) { - // Assert the presence of error message cy.wrap(text).should((content) => { expect(errorPatterns.some((pattern) => pattern.test(content))) .to.be.true; @@ -507,7 +509,6 @@ function verifyReturnUrl(redirection_url, expected_url, forward_flow) { payment_status !== "requires_capture" && payment_status !== "succeeded" ) { - // Assert payment status before screenshot cy.wrap(payment_status).should("exist"); cy.screenshot(`failed-payment-${payment_status}`); throw new Error( @@ -522,39 +523,21 @@ function verifyReturnUrl(redirection_url, expected_url, forward_flow) { ({ expected_url }) => { cy.window().its("location.origin").should("eq", expected_url); - cy.document().then((doc) => { - // For blank page in cross-origin - cy.wrap(doc.body.innerText.trim()).then((text) => { - if (text === "") { - // Assert before screenshot - cy.wrap(text).should("eq", ""); - cy.screenshot("cross-origin-blank-page"); - } - }); - - const errorPatterns = [ - /4\d{2}/, - /5\d{2}/, - /error/i, - /invalid request/i, - /server error/i, - ]; - - const pageText = doc.body.innerText.toLowerCase(); - cy.wrap(pageText).then((text) => { - if (errorPatterns.some((pattern) => pattern.test(text))) { - // Assert the presence of error message - cy.wrap(text).should((content) => { - expect(errorPatterns.some((pattern) => pattern.test(content))) - .to.be.true; - }); - cy.screenshot(`cross-origin-error-${Date.now()}`); - } - }); + Cypress.on("uncaught:exception", (err, runnable) => { + // Log the error details + // eslint-disable-next-line no-console + console.log( + `Error: ${err.message}\nError occurred in: ${runnable.title}\nStack trace: ${err.stack}` + ); + // Return false to prevent the error from failing the test + return false; }); } ); } + } catch (error) { + cy.error("Redirection verification failed:", error); + throw error; } } diff --git a/cypress-tests/cypress/utils/RequestBodyUtils.js b/cypress-tests/cypress/utils/RequestBodyUtils.js index 9b9015cad83..b6378551751 100644 --- a/cypress-tests/cypress/utils/RequestBodyUtils.js +++ b/cypress-tests/cypress/utils/RequestBodyUtils.js @@ -1,3 +1,18 @@ +const keyPrefixes = { + localhost: { + publishable_key: "pk_dev_", + key_id: "dev_", + }, + integ: { + publishable_key: "pk_snd_", + key_id: "snd_", + }, + sandbox: { + publishable_key: "pk_snd_", + key_id: "snd_", + }, +}; + export const setClientSecret = (requestBody, clientSecret) => { requestBody["client_secret"] = clientSecret; }; @@ -25,3 +40,37 @@ export const generateRandomString = (prefix = "cyMerchant") => { export const setMerchantId = (merchantCreateBody, merchantId) => { merchantCreateBody["merchant_id"] = merchantId; }; + +export function isoTimeTomorrow() { + const now = new Date(); + + // Create a new date object for tomorrow + const tomorrow = new Date(now); + tomorrow.setDate(now.getDate() + 1); + + // Convert to ISO string format + const isoStringTomorrow = tomorrow.toISOString(); + return isoStringTomorrow; +} + +export function validateEnv(baseUrl, keyIdType) { + if (!baseUrl) { + throw new Error("Please provide a baseUrl"); + } + + const environment = Object.keys(keyPrefixes).find((env) => + baseUrl.includes(env) + ); + + if (!environment) { + throw new Error("Unsupported baseUrl"); + } + + const prefix = keyPrefixes[environment][keyIdType]; + + if (!prefix) { + throw new Error(`Unsupported keyIdType: ${keyIdType}`); + } + + return prefix; +} diff --git a/cypress-tests/package-lock.json b/cypress-tests/package-lock.json index 9fb61a5da8d..57aef9f3b3e 100644 --- a/cypress-tests/package-lock.json +++ b/cypress-tests/package-lock.json @@ -9,13 +9,13 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "@eslint/js": "^9.17.0", + "@eslint/js": "^9.18.0", "cypress": "^13.17.0", "cypress-mochawesome-reporter": "^3.8.2", - "eslint": "^9.17.0", - "eslint-config-prettier": "^9.1.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", "eslint-plugin-cypress": "^4.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.2.3", "globals": "^15.14.0", "jsqr": "^1.4.0", "prettier": "^3.4.2" @@ -141,11 +141,14 @@ } }, "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==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -188,9 +191,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", - "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, "license": "MIT", "engines": { @@ -208,12 +211,13 @@ } }, "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==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, "license": "Apache-2.0", "dependencies": { + "@eslint/core": "^0.10.0", "levn": "^0.4.1" }, "engines": { @@ -1331,19 +1335,19 @@ } }, "node_modules/eslint": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", - "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "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/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.17.0", - "@eslint/plugin-kit": "^0.2.3", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", @@ -1391,13 +1395,13 @@ } }, "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==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", + "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", "dev": true, "license": "MIT", "bin": { - "eslint-config-prettier": "bin/cli.js" + "eslint-config-prettier": "build/bin/cli.js" }, "peerDependencies": { "eslint": ">=7.0.0" @@ -1417,9 +1421,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==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.3.tgz", + "integrity": "sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/cypress-tests/package.json b/cypress-tests/package.json index 7032a72fb08..a2e0a961e8f 100644 --- a/cypress-tests/package.json +++ b/cypress-tests/package.json @@ -8,10 +8,11 @@ "cypress": "npx cypress open", "cypress-e2e": "npx cypress run --e2e", "cypress:ci": "npx cypress run --headless", - "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:misc": "cypress run --headless --spec 'cypress/e2e/spec/Misc/**/*'", + "cypress:payment-method-list": "cypress run --headless --spec 'cypress/e2e/spec/PaymentMethodList/**/*'", + "cypress:payments": "cypress run --headless --spec 'cypress/e2e/spec/Payment/**/*'", + "cypress:payouts": "cypress run --headless --spec 'cypress/e2e/spec/Payout/**/*'", + "cypress:routing": "cypress run --headless --spec 'cypress/e2e/spec/Routing/**/*'", "format": "prettier --config .prettierrc . --write", "format:check": "prettier --config .prettierrc . --check", "lint": "eslint ." @@ -19,13 +20,13 @@ "author": "Hyperswitch", "license": "ISC", "devDependencies": { - "@eslint/js": "^9.17.0", + "@eslint/js": "^9.18.0", "cypress": "^13.17.0", "cypress-mochawesome-reporter": "^3.8.2", - "eslint": "^9.17.0", - "eslint-config-prettier": "^9.1.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", "eslint-plugin-cypress": "^4.1.0", - "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-prettier": "^5.2.3", "globals": "^15.14.0", "jsqr": "^1.4.0", "prettier": "^3.4.2" diff --git a/docker/wasm-build.Dockerfile b/docker/wasm-build.Dockerfile index 015a055e4fd..faa2d211bd8 100644 --- a/docker/wasm-build.Dockerfile +++ b/docker/wasm-build.Dockerfile @@ -1,7 +1,6 @@ FROM rust:latest as builder -ARG RUN_ENV=sandbox -ARG EXTRA_FEATURES="" +ARG FEATURES="" ARG VERSION_FEATURE_SET="v1" RUN apt-get update \ @@ -19,7 +18,7 @@ ENV env=$env COPY . . RUN echo env RUN cargo install wasm-pack -RUN wasm-pack build --target web --out-dir /tmp/wasm --out-name euclid crates/euclid_wasm -- --features ${VERSION_FEATURE_SET},${RUN_ENV},${EXTRA_FEATURES} +RUN wasm-pack build --target web --out-dir /tmp/wasm --out-name euclid crates/euclid_wasm -- --features ${VERSION_FEATURE_SET},${FEATURES} FROM scratch diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index feed9b9cb66..d9314ceb919 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -34,6 +34,7 @@ Please join us! - [Resolving a Bug Report](#resolving-a-bug-report) - [Pull Requests](#pull-requests) - [Cargo Commands](#cargo-commands) + - [Code Coverage](#code-coverage) - [Commits](#commits) - [Opening the Pull Request](#opening-the-pull-request) - [Discuss and update](#discuss-and-update) @@ -223,6 +224,74 @@ unstable features: cargo +nightly fmt ``` +### Code Coverage + +We appreciate well-tested code, so feel free to add tests when you can. + +To generate code coverage using the cypress tests, follow these steps: + +0. Make sure `grcov` and `llvm-tools-preview` are installed + + ```shell + rustup component add llvm-tools-preview + cargo install grcov + ``` + +1. Build the project with the `-Cinstrument-coverage` flag: + + ```shell + RUSTFLAGS="-Cinstrument-coverage" cargo build --bin=router --package=router + ``` + + Several `.profraw` files will be generated. (Due to the execution of build scripts) + +2. Execute the binary: + + ```shell + LLVM_PROFILE_FILE="coverage.profraw" target/debug/router + ``` + +3. Open a separate terminal tab and run the cypress tests, following the [README][cypress-v2-readme] + +4. After the tests have finished running, stop the `router` process using `Ctrl+C` + + The generated `coverage.profraw` file will contain the code coverage data for `router` + +5. Generate an html report from the data: + + ```shell + grcov . --source-dir . --output-type html --binary-path ./target/debug + ``` + +6. A folder named `html` will be generated, containing the report. You can view it using: + + ```shell + cd html && python3 -m http.server 8000 + ``` + +7. You can delete the generated `.profraw` files: + + ```shell + rm **/*.profraw + ``` + +Note: +- It is necessary to stop the `router` process to generate the coverage file +- Branch coverage generation requires nightly and currently `grcov` crashes while trying to include branch coverage. (Checked using `--log-level` parameter in `grcov`) + +#### Integration with VSCode +You can also visualize code coverage in VSCode using the [coverage-gutters](https://marketplace.visualstudio.com/items?itemName=ryanluker.vscode-coverage-gutters) extension. + +You need to generate an `lcov.info` file in the directory root. After following till step 4 above: + +```shell +grcov . -s . -t lcov --output-path lcov.info --binary-path ./target/debug --keep-only "crates/*" +``` + +This will generate an `lcov.info` file that can be read by the extension. + +[cypress-v2-readme]: /cypress-tests-v2/README.md + ### Commits It is a recommended best practice to keep your changes as logically grouped as diff --git a/justfile b/justfile index 43fca4afc89..5a0d13396ba 100644 --- a/justfile +++ b/justfile @@ -64,6 +64,22 @@ check_v2 *FLAGS: cargo check {{ check_flags }} --no-default-features --features "${FEATURES}" -- {{ FLAGS }} set +x +build_v2 *FLAGS: + #! /usr/bin/env bash + set -euo pipefail + + FEATURES="$(cargo metadata --all-features --format-version 1 --no-deps | \ + jq -r ' + [ .packages[] | select(.name == "router") | .features | keys[] # Obtain features of `router` package + | select( any( . ; test("(([a-z_]+)_)?v2") ) ) ] # Select v2 features + | join(",") # Construct a comma-separated string of features for passing to `cargo` + ')" + + set -x + cargo build --package router --bin router --no-default-features --features "${FEATURES}" {{ FLAGS }} + set +x + + run_v2: #! /usr/bin/env bash set -euo pipefail diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml index e90eb16ab61..ac90dc88198 100644 --- a/loadtest/config/development.toml +++ b/loadtest/config/development.toml @@ -48,12 +48,9 @@ ttl_for_storage_in_secs = 220752000 [forex_api] call_delay = 21600 -local_fetch_retry_count = 5 -local_fetch_retry_delay = 1000 -api_timeout = 20000 -api_key = "YOUR API KEY HERE" -fallback_api_key = "YOUR API KEY HERE" -redis_lock_timeout = 26000 +api_key = "" +fallback_api_key = "" +redis_lock_timeout = 100 [eph_key] validity = 1 @@ -94,6 +91,7 @@ bluesnap.secondary_base_url = "https://sandpay.bluesnap.com/" boku.base_url = "https://country-api4-stage.boku.com" braintree.base_url = "https://payments.sandbox.braintree-api.com/graphql" cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" +chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json index 48b7d410897..1cdee895b37 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario1-Create payment with confirm true/Payments - Create/request.json @@ -47,7 +47,7 @@ "payment_method_type": "debit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "01", "card_exp_year": "26", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario10-Create a mandate and recurring payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario10-Create a mandate and recurring payment/Payments - Create/request.json index b32011d26dc..47912f2025e 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario10-Create a mandate and recurring payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario10-Create a mandate and recurring payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario11-Refund recurring payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario11-Refund recurring payment/Payments - Create/request.json index 18f12b7306d..7dfbf639e51 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario11-Refund recurring payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario11-Refund recurring payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2-Create a payment and Confirm/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2-Create a payment and Confirm/Payments - Confirm/request.json index 540a2fa1946..8becf0a7c19 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2-Create a payment and Confirm/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2-Create a payment and Confirm/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "Joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario22- Update Amount/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario22- Update Amount/Payments - Confirm/request.json index 1b1757b9a49..e532d039fb1 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario22- Update Amount/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario22- Update Amount/Payments - Confirm/request.json @@ -49,7 +49,7 @@ "payment_method_type": "debit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "03", "card_exp_year": "2030", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario23-Add card flow/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario23-Add card flow/Payments - Create/request.json index 4f64a5d0e34..e895ace0e11 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario23-Add card flow/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario23-Add card flow/Payments - Create/request.json @@ -45,7 +45,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4111111111111111", + "card_number": "378282246310005", "card_exp_month": "03", "card_exp_year": "2030", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario26-Create payment without customer_id and with billing address and shipping address/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario26-Create payment without customer_id and with billing address and shipping address/Payments - Create/request.json index 627c816fba9..09ffe6396d3 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario26-Create payment without customer_id and with billing address and shipping address/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario26-Create payment without customer_id and with billing address and shipping address/Payments - Create/request.json @@ -47,7 +47,7 @@ "payment_method_type": "debit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "01", "card_exp_year": "26", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario27-Confirm a payment with requires_customer_action status/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario27-Confirm a payment with requires_customer_action status/Payments - Confirm/request.json index 1ce1d61eaa1..91acf28218e 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario27-Confirm a payment with requires_customer_action status/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario27-Confirm a payment with requires_customer_action status/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "Joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario28-Create payment with payment method billing/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario28-Create payment with payment method billing/Payments - Create/request.json index 578d3c47267..77323059b83 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario28-Create payment with payment method billing/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario28-Create payment with payment method billing/Payments - Create/request.json @@ -39,7 +39,7 @@ "payment_method_type": "debit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "01", "card_exp_year": "26", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario29-Update payment with payment method billing/Payments - Update/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario29-Update payment with payment method billing/Payments - Update/request.json index a8fc9965c7d..eafa6b9d22e 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario29-Update payment with payment method billing/Payments - Update/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario29-Update payment with payment method billing/Payments - Update/request.json @@ -21,7 +21,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "01", "card_exp_year": "26", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2a-Create payment with confirm false card holder name null/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2a-Create payment with confirm false card holder name null/Payments - Confirm/request.json index 604ac54144d..9e1278c7d95 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2a-Create payment with confirm false card holder name null/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2a-Create payment with confirm false card holder name null/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": null, diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2b-Create payment with confirm false card holder name empty/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2b-Create payment with confirm false card holder name empty/Payments - Confirm/request.json index 371ef616fe4..02de494d68c 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2b-Create payment with confirm false card holder name empty/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario2b-Create payment with confirm false card holder name empty/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json index 77f4d0dafe7..a0e82b8610d 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario3-Create payment without PMD/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario30-Pass payment method billing in Confirm/Payments - Confirm/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario30-Pass payment method billing in Confirm/Payments - Confirm/request.json index b92a83b5adc..2ded3043c3d 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario30-Pass payment method billing in Confirm/Payments - Confirm/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario30-Pass payment method billing in Confirm/Payments - Confirm/request.json @@ -41,7 +41,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "Joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Card CVC/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Card CVC/request.json index 77b40a8ece1..bfb1e3d863e 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Card CVC/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Card CVC/request.json @@ -23,7 +23,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry month/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry month/request.json index 2c3d0fe427c..6475ad1ef1a 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry month/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry month/request.json @@ -23,7 +23,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "13", "card_exp_year": "69", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry year/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry year/request.json index 63eda0afbe0..17a69bb2bfa 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry year/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Invalid Expiry year/request.json @@ -23,7 +23,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "22", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Success/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Success/request.json index 05bc9dbc321..baa616ddc75 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Success/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario31-Ensure API Contract for Payment Method Data/Payments - Card Payment Method Success/request.json @@ -23,7 +23,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - cvv check fails/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - cvv check fails/request.json index 9f5c6a8fb3a..ac816e25d30 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - cvv check fails/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - cvv check fails/request.json @@ -25,8 +25,8 @@ "payment_method_data": { "card": { "card_number": "4000000000000101", - "card_exp_month": "10", - "card_exp_year": "25", + "card_exp_month": "12", + "card_exp_year": "34", "card_holder_name": "joseph Doe", "card_cvc": "123" } diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - payment check populated for successful payment without billing/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - payment check populated for successful payment without billing/request.json index 88fccca9a0f..b6f0a69ef95 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - payment check populated for successful payment without billing/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - payment check populated for successful payment without billing/request.json @@ -24,7 +24,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - successful payment with billing/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - successful payment with billing/request.json index 28e45766722..2ebb0ebb813 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - successful payment with billing/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario32-Check is payment checks are populated/Payments - successful payment with billing/request.json @@ -24,7 +24,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json index 4deef11deb5..4a2876af98c 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4-Create payment with Manual capture/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4a-Create payment with manual_multiple capture/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4a-Create payment with manual_multiple capture/Payments - Create/request.json index f1ff4cb5692..978ad9bd542 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4a-Create payment with manual_multiple capture/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario4a-Create payment with manual_multiple capture/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json index 4deef11deb5..4a2876af98c 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario5-Void the payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9-Refund full payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9-Refund full payment/Payments - Create/request.json index f58c425653c..665946fccf9 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9-Refund full payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9-Refund full payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9a-Partial refund/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9a-Partial refund/Payments - Create/request.json index f58c425653c..665946fccf9 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9a-Partial refund/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Happy Cases/Scenario9a-Partial refund/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/QuickStart/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/QuickStart/Payments - Create/request.json index 2225c6096e3..322d38b08c6 100644 --- a/postman/collection-dir/stripe/Flow Testcases/QuickStart/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/QuickStart/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp Year)/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp Year)/request.json index 02e431466aa..3017be462df 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp Year)/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp Year)/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "2022", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp month)/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp month)/request.json index 52c73bea743..851b8538df1 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp month)/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario1-Create payment with Invalid card details/Payments - Create(Invalid Exp month)/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "01", "card_exp_year": "2023", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario10-Refund exceeds amount captured/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario10-Refund exceeds amount captured/Payments - Create/request.json index d6f53f92a04..c55925d85a5 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario10-Refund exceeds amount captured/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario10-Refund exceeds amount captured/Payments - Create/request.json @@ -34,7 +34,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario3-Capture greater amount/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario3-Capture greater amount/Payments - Create/request.json index 4deef11deb5..4a2876af98c 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario3-Capture greater amount/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario3-Capture greater amount/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario4-Capture the succeeded payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario4-Capture the succeeded payment/Payments - Create/request.json index f58c425653c..665946fccf9 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario4-Capture the succeeded payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario4-Capture the succeeded payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario5-Void the success_slash_failure payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario5-Void the success_slash_failure payment/Payments - Create/request.json index f58c425653c..665946fccf9 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario5-Void the success_slash_failure payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario5-Void the success_slash_failure payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario7-Refund exceeds amount/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario7-Refund exceeds amount/Payments - Create/request.json index f58c425653c..665946fccf9 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario7-Refund exceeds amount/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario7-Refund exceeds amount/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario8-Refund for unsuccessful payment/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario8-Refund for unsuccessful payment/Payments - Create/request.json index 3e1f1231ff8..e52dcb06a50 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario8-Refund for unsuccessful payment/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario8-Refund for unsuccessful payment/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario9-Create a recurring payment with greater mandate amount/Payments - Create/request.json b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario9-Create a recurring payment with greater mandate amount/Payments - Create/request.json index b32011d26dc..47912f2025e 100644 --- a/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario9-Create a recurring payment with greater mandate amount/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Flow Testcases/Variation Cases/Scenario9-Create a recurring payment with greater mandate amount/Payments - Create/request.json @@ -35,7 +35,7 @@ "payment_method": "card", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/PaymentMethods/PaymentMethods - Create/request.json b/postman/collection-dir/stripe/PaymentMethods/PaymentMethods - Create/request.json index 2617b3e44a0..f3b7f262b8f 100644 --- a/postman/collection-dir/stripe/PaymentMethods/PaymentMethods - Create/request.json +++ b/postman/collection-dir/stripe/PaymentMethods/PaymentMethods - Create/request.json @@ -22,7 +22,7 @@ "payment_method_type": "credit", "payment_method_issuer": "Visa", "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "John Doe" diff --git a/postman/collection-dir/stripe/PaymentMethods/Payments - Create/request.json b/postman/collection-dir/stripe/PaymentMethods/Payments - Create/request.json index 93bda640229..44e9559483d 100644 --- a/postman/collection-dir/stripe/PaymentMethods/Payments - Create/request.json +++ b/postman/collection-dir/stripe/PaymentMethods/Payments - Create/request.json @@ -45,7 +45,7 @@ "payment_method_type": "debit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Payments/Payments - Create Again/request.json b/postman/collection-dir/stripe/Payments/Payments - Create Again/request.json index c985bf50b0d..d0a12e7a4a0 100644 --- a/postman/collection-dir/stripe/Payments/Payments - Create Again/request.json +++ b/postman/collection-dir/stripe/Payments/Payments - Create Again/request.json @@ -36,7 +36,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Payments/Payments - Create Yet Again/request.json b/postman/collection-dir/stripe/Payments/Payments - Create Yet Again/request.json index 2b6d4bf3338..b7ecd39f2e7 100644 --- a/postman/collection-dir/stripe/Payments/Payments - Create Yet Again/request.json +++ b/postman/collection-dir/stripe/Payments/Payments - Create Yet Again/request.json @@ -36,7 +36,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Payments/Payments - Create/request.json b/postman/collection-dir/stripe/Payments/Payments - Create/request.json index 5a7457cedf9..a9b867f0f6f 100644 --- a/postman/collection-dir/stripe/Payments/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Payments/Payments - Create/request.json @@ -36,7 +36,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Payments/Payments - Update/request.json b/postman/collection-dir/stripe/Payments/Payments - Update/request.json index f3cdd29f872..5bc7fcdf2bc 100644 --- a/postman/collection-dir/stripe/Payments/Payments - Update/request.json +++ b/postman/collection-dir/stripe/Payments/Payments - Update/request.json @@ -34,7 +34,7 @@ "return_url": "https://duck.com", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/QuickStart/Payments - Create-copy/request.json b/postman/collection-dir/stripe/QuickStart/Payments - Create-copy/request.json index 5fcc5647594..a27c309c9ab 100644 --- a/postman/collection-dir/stripe/QuickStart/Payments - Create-copy/request.json +++ b/postman/collection-dir/stripe/QuickStart/Payments - Create-copy/request.json @@ -36,7 +36,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json b/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json index 13ed1a212de..24681fb62de 100644 --- a/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json +++ b/postman/collection-dir/stripe/QuickStart/Payments - Create/request.json @@ -36,7 +36,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-dir/stripe/Refunds/Payments - Create/request.json b/postman/collection-dir/stripe/Refunds/Payments - Create/request.json index d3219a30cf8..657d42351cb 100644 --- a/postman/collection-dir/stripe/Refunds/Payments - Create/request.json +++ b/postman/collection-dir/stripe/Refunds/Payments - Create/request.json @@ -37,7 +37,7 @@ "payment_method_type": "credit", "payment_method_data": { "card": { - "card_number": "4242424242424242", + "card_number": "378282246310005", "card_exp_month": "10", "card_exp_year": "25", "card_holder_name": "joseph Doe", diff --git a/postman/collection-json/stripe.postman_collection.json b/postman/collection-json/stripe.postman_collection.json index 329b444a41f..1f310172dc3 100644 --- a/postman/collection-json/stripe.postman_collection.json +++ b/postman/collection-json/stripe.postman_collection.json @@ -2505,7 +2505,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"},\"email\":\"example@example.com\"},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":{\"connector\":\"stripe\",\"merchant_connector_id\":\"{{merchant_connector_id}}\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"},\"email\":\"example@example.com\"},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":{\"connector\":\"stripe\",\"merchant_connector_id\":\"{{merchant_connector_id}}\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -2773,7 +2773,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":{\"connector\":\"stripe\",\"merchant_connector_id\":\"{{merchant_connector_id}}\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"},\"routing\":{\"type\":\"single\",\"data\":{\"connector\":\"stripe\",\"merchant_connector_id\":\"{{merchant_connector_id}}\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -3609,7 +3609,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -3814,7 +3814,7 @@ "language": "json" } }, - "raw": "{\"amount\":20000,\"currency\":\"SGD\",\"confirm\":false,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"email\":\"joseph@example.com\",\"name\":\"joseph Doe\",\"phone\":\"9123456789\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"payment_method\":\"card\",\"return_url\":\"https://duck.com\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"John\",\"last_name\":\"Doe\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"John\",\"last_name\":\"Doe\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":20000,\"currency\":\"SGD\",\"confirm\":false,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"email\":\"joseph@example.com\",\"name\":\"joseph Doe\",\"phone\":\"9123456789\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"payment_method\":\"card\",\"return_url\":\"https://duck.com\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"John\",\"last_name\":\"Doe\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"John\",\"last_name\":\"Doe\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id", @@ -4311,7 +4311,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -4558,7 +4558,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -4841,7 +4841,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -5272,7 +5272,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_issuer\":\"Visa\",\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"John Doe\"},\"customer_id\":\"{{customer_id}}\",\"metadata\":{\"city\":\"NY\",\"unit\":\"245\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_issuer\":\"Visa\",\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"John Doe\"},\"customer_id\":\"{{customer_id}}\",\"metadata\":{\"city\":\"NY\",\"unit\":\"245\"}}" }, "url": { "raw": "{{baseUrl}}/payment_methods", @@ -5470,7 +5470,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -6056,7 +6056,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+1\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -6593,7 +6593,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -6862,7 +6862,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"customer_acceptance\":{\"acceptance_type\":\"online\",\"accepted_at\":\"2022-09-10T10:11:12Z\",\"online\":{\"ip_address\":\"123.32.25.123\",\"user_agent\":\"Mozilla/5.0 (Linux; Android 12; SM-S906N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"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\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"customer_acceptance\":{\"acceptance_type\":\"online\",\"accepted_at\":\"2022-09-10T10:11:12Z\",\"online\":{\"ip_address\":\"123.32.25.123\",\"user_agent\":\"Mozilla/5.0 (Linux; Android 12; SM-S906N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"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\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -7272,7 +7272,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":null,\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":null,\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -7681,7 +7681,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -8080,7 +8080,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\"}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\"}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -8331,7 +8331,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -8723,7 +8723,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -9115,7 +9115,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -10435,7 +10435,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -10866,7 +10866,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -11636,7 +11636,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"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\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"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\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -12197,7 +12197,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"customer_acceptance\":{\"acceptance_type\":\"online\",\"accepted_at\":\"2022-09-10T10:11:12Z\",\"online\":{\"ip_address\":\"123.32.25.123\",\"user_agent\":\"Mozilla/5.0 (Linux; Android 12; SM-S906N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"customer_acceptance\":{\"acceptance_type\":\"online\",\"accepted_at\":\"2022-09-10T10:11:12Z\",\"online\":{\"ip_address\":\"123.32.25.123\",\"user_agent\":\"Mozilla/5.0 (Linux; Android 12; SM-S906N Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -17419,7 +17419,7 @@ "language": "json" } }, - "raw": "{\"client_secret\":\"{{client_secret}}\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"03\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"737\"}},\"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\"}},\"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\":\"128.0.0.1\"}}" + "raw": "{\"client_secret\":\"{{client_secret}}\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"03\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"737\"}},\"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\"}},\"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\":\"128.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -17643,7 +17643,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"stripesavecard_1234\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://google.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4111111111111111\",\"card_exp_month\":\"03\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"737\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"stripesavecard_1234\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://google.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"credit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"03\",\"card_exp_year\":\"2030\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"737\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"joseph\",\"last_name\":\"Doe\"},\"phone\":{\"number\":\"9123456789\",\"country_code\":\"+91\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -19983,7 +19983,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"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\"}},\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -20343,7 +20343,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -20501,7 +20501,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"business_country\":\"US\",\"business_label\":\"default\",\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"bernard123\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"setup_future_usage\":\"on_session\",\"payment_method\":\"card\",\"payment_method_type\":\"debit\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\",\"last_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -20836,7 +20836,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"01\",\"card_exp_year\":\"26\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}}" }, "url": { "raw": "{{baseUrl}}/payments/:id", @@ -21253,7 +21253,7 @@ "language": "json" } }, - "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" + "raw": "{\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"Joseph Doe\",\"card_cvc\":\"123\"},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}},\"client_secret\":\"{{client_secret}}\",\"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\":\"125.0.0.1\"}}" }, "url": { "raw": "{{baseUrl}}/payments/:id/confirm", @@ -21468,7 +21468,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -21602,7 +21602,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"13\",\"card_exp_year\":\"69\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"13\",\"card_exp_year\":\"69\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -21679,7 +21679,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"22\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"22\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -21758,7 +21758,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -21913,7 +21913,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4000000000000101\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4000000000000101\",\"card_exp_month\":\"12\",\"card_exp_year\":\"34\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -21999,7 +21999,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -22168,7 +22168,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrisoff Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"Narayan\",\"last_name\":\"Doe\"},\"email\":\"example@juspay.in\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -22295,7 +22295,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -22920,7 +22920,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"01\",\"card_exp_year\":\"2023\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"01\",\"card_exp_year\":\"2023\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -23053,7 +23053,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"2022\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"2022\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -23589,7 +23589,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"manual\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -23969,7 +23969,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -24230,7 +24230,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -24867,7 +24867,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -25204,7 +25204,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":false,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", @@ -25567,7 +25567,7 @@ "language": "json" } }, - "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"4242424242424242\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"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\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" + "raw": "{\"amount\":6540,\"currency\":\"USD\",\"confirm\":true,\"capture_method\":\"automatic\",\"capture_on\":\"2022-09-10T10:11:12Z\",\"amount_to_capture\":6540,\"customer_id\":\"StripeCustomer\",\"email\":\"guest@example.com\",\"name\":\"John Doe\",\"phone\":\"999999999\",\"phone_country_code\":\"+65\",\"description\":\"Its my first payment request\",\"authentication_type\":\"no_three_ds\",\"return_url\":\"https://duck.com\",\"payment_method\":\"card\",\"payment_method_data\":{\"card\":{\"card_number\":\"378282246310005\",\"card_exp_month\":\"10\",\"card_exp_year\":\"25\",\"card_holder_name\":\"joseph Doe\",\"card_cvc\":\"123\"}},\"setup_future_usage\":\"off_session\",\"mandate_data\":{\"customer_acceptance\":{\"acceptance_type\":\"offline\",\"accepted_at\":\"1963-05-03T04:07:52.723Z\",\"online\":{\"ip_address\":\"127.0.0.1\",\"user_agent\":\"amet irure esse\"}},\"mandate_type\":{\"single_use\":{\"amount\":7000,\"currency\":\"USD\"}}},\"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\"}},\"billing\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"shipping\":{\"address\":{\"line1\":\"1467\",\"line2\":\"Harrison Street\",\"line3\":\"Harrison Street\",\"city\":\"San Fransico\",\"state\":\"California\",\"zip\":\"94122\",\"country\":\"US\",\"first_name\":\"sundari\"}},\"statement_descriptor_name\":\"joseph\",\"statement_descriptor_suffix\":\"JS\",\"metadata\":{\"udf1\":\"value1\",\"new_customer\":\"true\",\"login_date\":\"2019-09-10T10:11:12Z\"}}" }, "url": { "raw": "{{baseUrl}}/payments", diff --git a/proto/elimination_rate.proto b/proto/elimination_rate.proto index c5f10597ade..d585dd2494b 100644 --- a/proto/elimination_rate.proto +++ b/proto/elimination_rate.proto @@ -28,8 +28,17 @@ message EliminationResponse { message LabelWithStatus { string label = 1; - bool is_eliminated = 2; - string bucket_name = 3; + EliminationInformation elimination_information = 2; +} + +message EliminationInformation { + BucketInformation entity = 1; + BucketInformation global = 2; +} + +message BucketInformation { + bool is_eliminated = 1; + repeated string bucket_name = 2; } // API-2 types @@ -64,4 +73,4 @@ message InvalidateBucketResponse { BUCKET_INVALIDATION_FAILED = 1; } InvalidationStatus status = 1; -} \ No newline at end of file +} diff --git a/scripts/add_connector.sh b/scripts/add_connector.sh index 108e9d88263..32d24fe47eb 100755 --- a/scripts/add_connector.sh +++ b/scripts/add_connector.sh @@ -6,7 +6,7 @@ function find_prev_connector() { git checkout $self cp $self $self.tmp # Add new connector to existing list and sort it - connectors=(aci adyen adyenplatform airwallex amazonpay applepay authorizedotnet bambora bamboraapac bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource datatrans deutschebank digitalvirgo dlocal dummyconnector ebanx elavon fiserv fiservemea fiuu forte globalpay globepay gocardless gpayments helcim iatapay inespay itaubank jpmorgan klarna mifinity mollie multisafepay netcetera nexinets nexixpay nomupay noon novalnet nuvei opayo opennode paybox payeezy payme payone paypal payu placetopay plaid powertranz prophetpay rapyd razorpay redsys shift4 square stax stripe taxjar threedsecureio thunes trustpay tsys unified_authentication_service volt wellsfargo wellsfargopayout wise worldline worldpay xendit zsl "$1") + connectors=(aci adyen adyenplatform airwallex amazonpay applepay authorizedotnet bambora bamboraapac bankofamerica billwerk bitpay bluesnap boku braintree cashtocode chargebee checkout coinbase cryptopay cybersource datatrans deutschebank digitalvirgo dlocal dummyconnector ebanx elavon fiserv fiservemea fiuu forte globalpay globepay gocardless gpayments helcim iatapay inespay itaubank jpmorgan klarna mifinity mollie multisafepay netcetera nexinets nexixpay nomupay noon novalnet nuvei opayo opennode paybox payeezy payme payone paypal payu placetopay plaid powertranz prophetpay rapyd razorpay redsys shift4 square stax stripe taxjar threedsecureio thunes trustpay tsys unified_authentication_service volt wellsfargo wellsfargopayout wise worldline worldpay xendit zsl "$1") IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS res="$(echo ${sorted[@]})" sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp diff --git a/scripts/execute_cypress.sh b/scripts/execute_cypress.sh index 1f1219ee717..8d93519b468 100755 --- a/scripts/execute_cypress.sh +++ b/scripts/execute_cypress.sh @@ -158,12 +158,13 @@ function cleanup() { function main() { local command="${1:-}" local jobs="${2:-5}" + local test_dir="${3:-cypress-tests}" - # Ensure script runs from 'cypress-tests' directory - if [[ "$(basename "$PWD")" != "cypress-tests" ]]; then - print_color "yellow" "Changing directory to 'cypress-tests'..." - cd cypress-tests || { - print_color "red" "ERROR: Directory 'cypress-tests' not found!" + # Ensure script runs from the specified test directory (default: cypress-tests) + if [[ "$(basename "$PWD")" != "$(basename "$test_dir")" ]]; then + print_color "yellow" "Changing directory to '${test_dir}'..." + cd "${test_dir}" || { + print_color "red" "ERROR: Directory '${test_dir}' not found!" exit 1 } fi