hyperswitch icon indicating copy to clipboard operation
hyperswitch copied to clipboard

feat(core): [Network Token] Passing Network Token in payments request

Open ImSagnik007 opened this issue 2 months ago • 9 comments

Type of Change

  • [ ] Bugfix
  • [x] New feature
  • [ ] Enhancement
  • [ ] Refactoring
  • [ ] Dependency updates
  • [ ] Documentation
  • [ ] CI/CD

Description

Network Token Added as a payment method. Network Token to be passed directly in Payments Request:

  1. For normal and CIT payment: Network Token + Cryptogram
#[derive(Default, Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct NetworkTokenData {
    /// The network token
    #[schema(value_type = String, example = "4242424242424242")]
    pub network_token: CardNumber,

    /// The token's expiry month
    #[schema(value_type = String, example = "05")]
    pub token_exp_month: Secret<String>,

    /// The token's expiry year
    #[schema(value_type = String, example = "24")]
    pub token_exp_year: Secret<String>,

    /// The token cryptogram
    #[schema(value_type = Option<String>)]
    pub token_cryptogram: Option<Secret<String>>,
}
  1. For MIT payment: Network Token + NTI
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
pub struct NetworkTransactionIdAndNetworkTokenDetails {
    /// The Network Token
    #[schema(value_type = String, example = "4242424242424242")]
    pub network_token: cards::CardNumber,

    /// The token's expiry month
    #[schema(value_type = String, example = "05")]
    pub token_exp_month: Secret<String>,

    /// The token's expiry year
    #[schema(value_type = String, example = "24")]
    pub token_exp_year: Secret<String>,

    /// The token's network
    #[schema(value_type = Option<CardNetwork>, example = "Visa")]
    pub network: Option<api_enums::CardNetwork>,

    /// The network transaction ID provided by the card network during a Customer Initiated Transaction (CIT)
    /// where `off_session` is true.
    #[schema(value_type = String)]
    pub network_transaction_id: Secret<String>,
}

Solution Doc: https://docs.google.com/document/d/1trPRKzexBHQwGHmDZ_ixqRmcMiaehu3TOpv136JOXsw/edit?usp=sharing

Additional Changes

  • [x] This PR modifies the API contract
  • [ ] This PR modifies the database schema
  • [ ] This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

  1. Merchant Acc create
  2. API key create
  3. Connector create:
curl --location 'http://localhost:8080/account/merchant_1761292607/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_MARy9LQgElvWpiESgZY3WgYYEGSIBoQmpGDsoheuhAhs0Vj8HpdBOqyvxQOqcvQt' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "cybersource",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_secret": "",
        "api_key": "",
        "key1": ""
    },
    "test_mode": true,
    "disabled": false,
    "payment_methods_enabled": [
        {
            "payment_method": "wallet",
            "payment_method_types": [
                {
                    "payment_method_type": "google_pay",
                    "payment_experience": "invoke_sdk_client",
                    "card_networks": null,
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "network_token",
            "payment_method_types": [
                {
                    "payment_method_type": "network_token",
                    "payment_experience": null,
                    "card_networks": null,
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": 1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        },
        {
            "payment_method": "card",
            "payment_method_types": [
                {
                    "payment_method_type": "credit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard",
                        "AmericanExpress"
                    ],
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": -1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                },
                {
                    "payment_method_type": "debit",
                    "payment_experience": null,
                    "card_networks": [
                        "Visa",
                        "Mastercard"
                    ],
                    "accepted_currencies": null,
                    "accepted_countries": null,
                    "minimum_amount": -1,
                    "maximum_amount": 68607706,
                    "recurring_enabled": true,
                    "installment_payment_enabled": true
                }
            ]
        }
    ],
    "metadata": {
        "status_url": "https://2753-2401-4900-1cb8-2ff9-24dd-1ccf-ed12-b464.in.ngrok.io/webhooks/merchant_1678699058/globalpay",
        "account_name": "transaction_processing",
        "pricing_type": "fixed_price",
        "acquirer_bin": "438309",
        "acquirer_merchant_id": "00002000000"
    },
    "business_country": "US",
    "business_label": "default",
    "frm_configs": null,
    "connector_webhook_details": {
        "merchant_secret": ""
    }
}'
  1. Payments create:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_Qb8sXXnto02KhH9HKhJzN9V5VbfOOXCVJBx3Jmveu14XgHQ3wOOVu5pKTLEOZsHc' \
--data-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": "[email protected]",
  "name": "John Doe",
  "phone": "999999999",
  "phone_country_code": "+1",
  "description": "Its my first payment request",
  "authentication_type": "no_three_ds",
  "return_url": "https://google.com",
  "setup_future_usage": "on_session",
  "payment_method": "network_token",
  "payment_method_type": "network_token",
  "payment_method_data": {
    "network_token": {
      "network_token": "",
      "token_exp_month": "12",
      "token_exp_year": "26",
      "token_cryptogram": ""
    }
  },
  "billing": {
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US",
      "first_name": "joseph",
      "last_name": "Doe"
    },
    "phone": {
      "number": "8056594427",
      "country_code": "+91"
    }
  },
  "shipping": {
    "address": {
      "line1": "1467",
      "line2": "Harrison Street",
      "line3": "Harrison Street",
      "city": "San Fransico",
      "state": "California",
      "zip": "94122",
      "country": "US",
      "first_name": "joseph",
      "last_name": "Doe"
    },
    "phone": {
      "number": "8056594427",
      "country_code": "+91"
    }
  },
  "statement_descriptor_name": "joseph",
  "statement_descriptor_suffix": "JS",
  "metadata": {
    "udf1": "value1",
    "new_customer": "true",
    "login_date": "2019-09-10T10:11:12Z"
  }
}'
  1. Payments Create CIT:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_eTv2dhqRaLPG86yfGSYsdpwdkt90Tl0mVFUIfPtKxUVW3RhNryspwSG6930c7LBB' \
--data-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": "[email protected]",
  "name": "John Doe",
  "phone": "999999999",
  "phone_country_code": "+1",
  "description": "Its my first payment request",
  "authentication_type": "no_three_ds",
  "return_url": "https://google.com",
  "setup_future_usage": "off_session",
  "payment_type": "setup_mandate",
  "payment_method": "network_token",
  "payment_method_type": "network_token",
  "payment_method_data": {
    "network_token": {
      "network_token": "",
      "token_exp_month": "12",
      "token_exp_year": "26",
      "token_cryptogram": ""
    }
  },
  "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "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": "joseph",
      "last_name": "Doe"
    },
    "phone": {
      "number": "8056594427",
      "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": "8056594427",
      "country_code": "+91"
    }
  },
  "statement_descriptor_name": "joseph",
  "statement_descriptor_suffix": "JS",
  "metadata": {
    "udf1": "value1",
    "new_customer": "true",
    "login_date": "2019-09-10T10:11:12Z"
  }
}'
  1. Payments Create MIT:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_eTv2dhqRaLPG86yfGSYsdpwdkt90Tl0mVFUIfPtKxUVW3RhNryspwSG6930c7LBB' \
--data '{
    "amount": 999,
    "currency": "USD",
    "confirm": true,
    "profile_id": "pro_ArBaOyc24CoPMaqbFx8O",
    "customer_id": "StripeCustomer",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_pMutHGTtUekgMcPgKE1k"
    },
    "off_session": true,
    "billing": {
        "address": {
            "first_name":"John",
            "last_name":"Doe",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US"
        },
         "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "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"
    }
    
}'

Checklist

  • [x] I formatted the code cargo +nightly fmt --all
  • [x] I addressed lints thrown by cargo clippy
  • [x] I reviewed the submitted code
  • [ ] I added unit tests for my changes where possible

ImSagnik007 avatar Oct 24 '25 08:10 ImSagnik007

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs  84% smaller
  crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs  84% smaller
  crates/router/src/core/payout_link.rs  83% smaller
  crates/connector_configs/src/transformer.rs  83% smaller
  crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs  82% smaller
  crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs  82% smaller
  crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs  78% smaller
  crates/hyperswitch_connectors/src/connectors/klarna.rs  78% smaller
  crates/hyperswitch_connectors/src/connectors/noon/transformers.rs  76% smaller
  crates/router/src/core/payments.rs  76% smaller
  crates/hyperswitch_connectors/src/connectors/barclaycard/transformers.rs  76% smaller
  crates/hyperswitch_connectors/src/connectors/payeezy/transformers.rs  76% smaller
  crates/hyperswitch_connectors/src/connectors/fiuu/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/worldline/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/wellsfargo/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/fiserv/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/nmi/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/braintree/transformers.rs  75% smaller
  crates/hyperswitch_connectors/src/connectors/archipel/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/aci/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/bambora/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/bluesnap/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/boku/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/cryptopay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/datatrans/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/dlocal/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/facilitapay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/forte/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/globepay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/gocardless/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/helcim/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/iatapay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/itaubank/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/mifinity/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/opayo/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/placetopay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/powertranz/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/square/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/stax/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/tsys/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/volt/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/zen/transformers.rs  74% smaller
  crates/hyperswitch_connectors/src/connectors/nexinets/transformers.rs  73% smaller
  crates/router/src/core/payments/operations/payment_response.rs  70% smaller
  crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs  69% smaller
  crates/hyperswitch_connectors/src/connectors/payme/transformers.rs  68% smaller
  crates/kgraph_utils/src/transformers.rs  67% smaller
  crates/hyperswitch_connectors/src/connectors/nexixpay/transformers.rs  63% smaller
  crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs  60% smaller
  crates/euclid/src/frontend/dir/transformers.rs  58% smaller
  crates/router/src/core/payments/helpers.rs  29% smaller
  crates/hyperswitch_connectors/src/connectors/adyen.rs  20% smaller
  crates/hyperswitch_connectors/src/connectors/breadpay/transformers.rs  18% smaller
  crates/hyperswitch_connectors/src/connectors/celero/transformers.rs  18% smaller
  crates/hyperswitch_connectors/src/connectors/jpmorgan/transformers.rs  18% smaller
  crates/hyperswitch_connectors/src/connectors/tesouro/transformers.rs  18% smaller
  crates/hyperswitch_connectors/src/connectors/zsl/transformers.rs  18% smaller
  crates/hyperswitch_connectors/src/connectors/nordea/transformers.rs  17% smaller
  crates/hyperswitch_connectors/src/connectors/redsys/transformers.rs  17% smaller
  crates/api_models/src/payments.rs  9% smaller
  crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs  9% smaller
  crates/openapi/src/openapi.rs  5% smaller
  crates/hyperswitch_domain_models/src/payment_method_data.rs  5% smaller
  api-reference/v1/openapi_spec_v1.json  3% smaller
  crates/router/src/routes/payments.rs  3% smaller
  crates/hyperswitch_connectors/src/utils.rs  1% smaller
  crates/api_models/src/mandates.rs  0% smaller
  crates/api_models/src/routing.rs  0% smaller
  crates/common_enums/src/enums.rs  0% smaller
  crates/common_enums/src/transformers.rs  0% smaller
  crates/common_types/src/payments.rs  0% smaller
  crates/connector_configs/src/response_modifier.rs  0% smaller
  crates/euclid/src/dssa/graph.rs  0% smaller
  crates/euclid/src/frontend/ast/lowering.rs  0% smaller
  crates/euclid/src/frontend/dir.rs  0% smaller
  crates/euclid/src/frontend/dir/enums.rs  0% smaller
  crates/euclid/src/frontend/dir/lowering.rs  0% smaller
  crates/euclid_wasm/src/lib.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/cybersource.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/peachpayments.rs  0% smaller
  crates/kgraph_utils/src/mca.rs  0% smaller
  crates/payment_methods/src/helpers.rs  0% smaller
  crates/router/src/connector/utils.rs  0% smaller
  crates/router/src/core/payments/routing/utils.rs  0% smaller
  crates/router/src/types/transformers.rs  0% smaller

semanticdiff-com[bot] avatar Oct 24 '25 08:10 semanticdiff-com[bot]

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :warning: Please upload report for BASE (main@4174929). Learn more about missing BASE report.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #9975   +/-   ##
=======================================
  Coverage        ?   45.99%           
=======================================
  Files           ?       32           
  Lines           ?     3692           
  Branches        ?        0           
=======================================
  Hits            ?     1698           
  Misses          ?     1994           
  Partials        ?        0           

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Oct 24 '25 08:10 codecov[bot]

Can we have clear title and description? changes done in the pr? this is not self-explanatory

prasunna09 avatar Oct 27 '25 06:10 prasunna09

Can we have clear title and description? changes done in the pr? this is not self-explanatory

Can you check the solution doc, already attached in the description.

ImSagnik007 avatar Oct 27 '25 07:10 ImSagnik007

did we test out the pre network tokenization and save card flow for this? Please test all the flows that includes network tokenization.

prasunna09 avatar Oct 31 '25 09:10 prasunna09

did we test out the pre network tokenization and save card flow for this? Please test all the flows that includes network tokenization.

can you please explain why do we need to test all the flows that include network tokenization? pre network tokenization and save card flow are for cards right? This is a whole new payment method.

ImSagnik007 avatar Nov 10 '25 04:11 ImSagnik007

did we test out the pre network tokenization and save card flow for this? Please test all the flows that includes network tokenization.

can you please explain why do we need to test all the flows that include network tokenization? pre network tokenization and save card flow are for cards right? This is a whole new payment method.

due to poor pr tittle and description, not able to under stand why this is introduced. here, it is mentioned Network Token Payment Method , but in changes, it has network transaction id and network token?

Can we please follow the commit guidelines - https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md#commits

prasunna09 avatar Nov 10 '25 09:11 prasunna09

did we test out the pre network tokenization and save card flow for this? Please test all the flows that includes network tokenization.

can you please explain why do we need to test all the flows that include network tokenization? pre network tokenization and save card flow are for cards right? This is a whole new payment method.

due to poor pr tittle and description, not able to under stand why this is introduced. here, it is mentioned Network Token Payment Method , but in changes, it has network transaction id and network token?

Can we please follow the commit guidelines - https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md#commits

Can you check the PR description? The solution doc is already attached to it, the problem statement and expected solution is mentioned over there. Also I attached a github issue, renamed the title. can you review the PR now?

ImSagnik007 avatar Nov 10 '25 11:11 ImSagnik007

also can we fix the clippy for both v1 and v2?

prasunna09 avatar Nov 10 '25 11:11 prasunna09