Skip to content

feat(core): [Network Tokenization] pre network tokenization#6873

Merged
likhinbopanna merged 3 commits intomainfrom
pre_network_tokenization
May 19, 2025
Merged

feat(core): [Network Tokenization] pre network tokenization#6873
likhinbopanna merged 3 commits intomainfrom
pre_network_tokenization

Conversation

@ImSagnik007
Copy link
Contributor

@ImSagnik007 ImSagnik007 commented Dec 18, 2024

Type of Change

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

Description

Introduced a new field in business_profile (is_pre_network_tokenization_enabled).
Based on that field the card will be tokenized before first payment.
If the payment get succeeded the card and network token data will be stored in the locker afterwards.

Additional Changes

  • 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. Enable is_network_tokenization_enabled and is_pre_network_tokenization_enabled in business_profile
  2. Create a card payment with a network tokenization supported connector. (Customer acceptance should be there)

Connector Create(Cybersource):

curl --location 'http://localhost:8080/account/merchant_1747299015/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_6YZ1hGvUYrgBzKrKO25WteTts6KvLVXCodhEmuqaogJZvLhGIEVSVNftVcZytpdE' \
--data '{
    "connector_type": "payment_processor",
    "connector_name": "cybersource",
    "connector_account_details": {
        "auth_type": "SignatureKey",
        "api_secret": "abc",
        "api_key": "abc",
        "key1": "abc"
    },
    "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": "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": "url",
        "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": "abc"
    }
}'

Payments Create:

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data-raw '{
    "amount": 10,
    "amount_to_capture": 10,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "customer1747403711",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "setup_future_usage": "on_session",
    "return_url": "http://127.0.0.1:4040",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    },
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "card_number": "4761360080000093",
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "joseph Doe",
            "card_cvc": "947"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US"
        },
        "email": "soppa@gmail.com"
    },
    "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"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
    
}'

Response:

{
    "payment_id": "pay_hW2g73Y3LCCl8K59On4s",
    "merchant_id": "merchant_1747404722",
    "status": "succeeded",
    "amount": 10,
    "net_amount": 10,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 10,
    "connector": "cybersource",
    "client_secret": "abc",
    "created": "2025-05-16T14:13:37.029Z",
    "currency": "USD",
    "customer_id": "customer1747404817",
    "customer": {
        "id": "customer1747404817",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": "on_session",
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "0093",
            "card_type": "DEBIT",
            "card_network": "Visa",
            "card_issuer": "BANKMUSCAT (SAOG)",
            "card_issuing_country": "OMAN",
            "card_isin": "476136",
            "card_extended_bin": null,
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": null,
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": null,
            "last_name": null
        },
        "phone": null,
        "email": "soppa@gmail.com"
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "http://127.0.0.1:4040/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "debit",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "customer1747404817",
        "created_at": 1747404816,
        "expires": 1747408416,
        "secret": "abc"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "abc",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pay_hW2g73Y3LCCl8K59On4s_1",
    "payment_link": null,
    "profile_id": "pro_cjkyoVtfdaQY5JKvfh3v",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_WI36rV75QJhAyHC02iup",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-05-16T14:28:37.028Z",
    "fingerprint": null,
    "browser_info": {
        "language": "nl-NL",
        "time_zone": 0,
        "ip_address": "125.0.0.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1536,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 723,
        "java_script_enabled": true
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2025-05-16T14:13:44.489Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": "manual",
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null
}

Logs:
Raw Connector Request:

raw_connector_request: Object {"processingInformation": Object {"actionList": Null, "actionTokenTypes": Null, "authorizationOptions": Object {"initiator": Null, "merchantIntitiatedTransaction": Null, "ignoreAvsResult": Null, "ignoreCvResult": Null}, "commerceIndicator": String("internet"), "capture": Bool(true), "captureOptions": Null, "paymentSolution": Null}, "paymentInformation": Object {"tokenizedCard": Object {"number": String("460400**********"), "expirationMonth": String("*** alloc::string::String ***"), "expirationYear": String("*** alloc::string::String ***"), "cryptogram": String("*** alloc::string::String ***"), "transactionType": String("1")}}, "orderInformation": Object {"amountDetails": Object {"totalAmount": String("0.10"), "currency": String("USD")}, "billTo": Object {"firstName": String("*** alloc::string::String ***"), "lastName": String("*** alloc::string::String ***"), "address1": String("*** alloc::string::String ***"), "locality": String("San Fransico"), "administrativeArea": String("*** alloc::string::String ***"), "postalCode": String("*** alloc::string::String ***"), "country": String("US"), "email": String("*****@example.com")}}, "clientReferenceInformation": Object {"code": String("pay_hW2g73Y3LCCl8K59On4s_1")}, "merchantDefinedInformation": Array [Object {"key": Number(1), "value": String("login_date=\"2019-09-10T10:11:12Z\"")}, Object {"key": Number(2), "value": String("new_customer=\"true\"")}, Object {"key": Number(3), "value": String("udf1=\"value1\"")}]}

Checklist

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

@ImSagnik007 ImSagnik007 self-assigned this Dec 18, 2024
@ImSagnik007 ImSagnik007 requested review from a team as code owners December 18, 2024 06:19
@semanticdiff-com
Copy link

semanticdiff-com bot commented Dec 18, 2024

Review changes with  SemanticDiff

Changed Files
File Status
  cypress-tests/cypress/e2e/configs/Payment/Noon.js  100% smaller
  cypress-tests/cypress/support/commands.js  100% smaller
  crates/router/src/core/payments/helpers.rs  64% smaller
  crates/router/src/core/payments/tokenization.rs  30% smaller
  crates/router/src/core/payments/transformers.rs  1% smaller
  crates/router/src/core/payments.rs  1% smaller
  crates/api_models/src/admin.rs  0% smaller
  crates/diesel_models/src/business_profile.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/hyperswitch_domain_models/src/business_profile.rs  0% smaller
  crates/hyperswitch_domain_models/src/payment_method_data.rs  0% smaller
  crates/hyperswitch_domain_models/src/payments.rs  0% smaller
  crates/router/src/core/admin.rs  0% smaller
  crates/router/src/core/payments/operations/payment_response.rs  0% smaller
  crates/router/src/types/api/admin.rs  0% smaller
  migrations/2025-05-16-064616_add_is_pre_network_tokenization_enabled_in_business_profile/down.sql Unsupported file format
  migrations/2025-05-16-064616_add_is_pre_network_tokenization_enabled_in_business_profile/up.sql Unsupported file format
  v2_migrations/2025-05-05-073505_remove_is_pre_network_tokenization_enabled_from_business_profile/down.sql Unsupported file format
  v2_migrations/2025-05-05-073505_remove_is_pre_network_tokenization_enabled_from_business_profile/up.sql Unsupported file format

@ImSagnik007 ImSagnik007 linked an issue Dec 18, 2024 that may be closed by this pull request
2 tasks
@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Dec 18, 2024
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 276d588 to 5c13cc8 Compare December 23, 2024 06:06
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 23, 2024
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from a5845b1 to 3f9c0ba Compare December 23, 2024 08:49
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 23, 2024
@ImSagnik007 ImSagnik007 changed the title Pre network tokenization feat(core): [Network Tokenization] pre network tokenization Dec 23, 2024
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 23, 2024
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 16e0f52 to dcc8625 Compare December 25, 2024 06:13
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Dec 25, 2024
Copy link
Contributor

@prasunna09 prasunna09 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also when constructing router data, if pre-tokenization enabled, we need to pass network token data as payment method data. Could you point me to that change?

Comment on lines 473 to 474
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this validation for pre-network tokenization move to a a function?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we ignoring this token_ref? this should be set in payment method info right?

Comment on lines 467 to 471
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do no filter out. check only if the connector decided by routing is in the network tokenization supported connectors. this is because routing should always be prioritized over any feature. please remove this.

Comment on lines 627 to 629
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is same logic, can you write this to a common function?

@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 4c8d6a4 to 7563104 Compare January 6, 2025 05:49
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 6, 2025

/// Indicates if network tokenization before first payment is enabled or not
#[serde(default)]
pub is_tokenize_before_payment_enabled: bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_tokenize_before_payment_enabled is bit ambiguous when 'before payment' is mentioned in variable name.

is_pre_network_tokenization_enabled can be used ig. We can add clear doc comment


let is_nt_supported_connector = ntid_supported_connectors.contains(&connector_data.connector_name);

println!("{:?}<<>>10",is_nt_supported_connector);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the loggers.

println!("{:?}<<>>10",is_nt_supported_connector);

if is_pre_tokenization_enabled && is_nt_supported_connector {
println!("{:?}<<>>14",is_nt_supported_connector);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here ^

if is_pre_tokenization_enabled && is_nt_supported_connector {
println!("{:?}<<>>14",is_nt_supported_connector);
save_card_and_network_token_data(state, &mut payment_data).await;
println!("{:?}<<>>15",payment_data.get_payment_method_data());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this too^

network_token_data: token_data.clone(),
ref_id: token_ref
};
println!("{:?}<<>>17", network_token_data_for_vault);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove logger here^

#[derive(Default, Clone, serde::Serialize, Debug)]
pub struct NetworkTokenDataForVault {
pub network_token_data: hyperswitch_domain_models::payment_method_data::NetworkTokenData,
pub ref_id: String,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is network_token_req_ref id right?
Can you rename it?


if is_pre_tokenization_enabled && is_nt_supported_connector {
println!("{:?}<<>>14",is_nt_supported_connector);
save_card_and_network_token_data(state, &mut payment_data).await;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you modify save_card_and_network_token_data fn name? because, the fn is trying to pre tokenize and update payment data.payment method data. but not saving card flow.

}

#[derive(Default, Clone, serde::Serialize, Debug)]
pub struct CardDataForVault {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems like this struct has never been used. if this is not needed, can you remove this?

.await.ok();
match pre_tokenization_response {
Some((Some(token_response), Some(token_ref))) => {
let token_data = domain::NetworkTokenData {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be moved to a From implementation?

Some(token_response),
network_token_requestor_ref_id.clone(),
)),
_ => Ok((None, None)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incase fetch cryptogram fails we need to delete the network token generated right?
you return Ok((None, None)) in this failure case.

in save_card_and_network_token_data fn, it is written that if pre_payment_tokenization is None, then vault operation is set to SaveCardData(api::Card). but we need to return network token requestor ref id right? so that we can use this id to delete network token at token requestor in post update tracker

@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch 3 times, most recently from d3d4ecf to 90da476 Compare January 20, 2025 09:55
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Jan 20, 2025
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 4b62178 to 6bb59b2 Compare January 21, 2025 11:29
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 21, 2025
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from a699724 to 9311c2c Compare January 22, 2025 08:59
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Jan 22, 2025
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels May 5, 2025
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from a73f164 to 57396fb Compare May 5, 2025 12:07
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label May 5, 2025
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 57396fb to 4cfa5db Compare May 5, 2025 12:08
Comment on lines +2715 to +2718

/// Indicates if pre network tokenization is enabled or not
#[schema(default = false, example = false)]
pub is_pre_network_tokenization_enabled: Option<bool>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be removed from all v2 structs

@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 4cfa5db to 038d6f1 Compare May 6, 2025 15:36
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label May 6, 2025
hrithikesh026
hrithikesh026 previously approved these changes May 8, 2025
Copy link
Contributor

@hrithikesh026 hrithikesh026 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

prasunna09
prasunna09 previously approved these changes May 12, 2025
@@ -0,0 +1,2 @@
-- Your SQL goes here
ALTER TABLE business_profile DROP COLUMN IF EXISTS is_pre_network_tokenization_enabled; No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we are removing here? the feature should be available in v2 also

@@ -0,0 +1,2 @@
-- Your SQL goes here
ALTER TABLE business_profile ADD COLUMN IF NOT EXISTS is_pre_network_tokenization_enabled BOOLEAN NOT NULL DEFAULT FALSE; No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove default and handle the default logic in code, basically when its null, change it to default in code

#[cfg(feature = "v1")]
pub async fn set_payment_method_data_for_pre_network_tokenization<F, D>(
state: &SessionState,
payment_data: &mut D,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Write logic in a way so that mutation is not required in this function, basically do things and return output, so that only in one place mutation is handled

jarnura
jarnura previously approved these changes May 13, 2025
@ImSagnik007 ImSagnik007 dismissed stale reviews from jarnura, prasunna09, and hrithikesh026 via 3d03326 May 15, 2025 09:01
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from a75adef to 3d03326 Compare May 15, 2025 09:01
@hyperswitch-bot hyperswitch-bot bot removed the M-api-contract-changes Metadata: This PR involves API contract changes label May 15, 2025
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 3d03326 to 4c2d1b4 Compare May 15, 2025 10:03
@ImSagnik007 ImSagnik007 force-pushed the pre_network_tokenization branch from 4c2d1b4 to a0b5e24 Compare May 16, 2025 07:02
@hyperswitch-bot hyperswitch-bot bot requested a review from a team as a code owner May 16, 2025 07:03
@ImSagnik007 ImSagnik007 removed the request for review from a team May 16, 2025 08:09
@likhinbopanna likhinbopanna added this pull request to the merge queue May 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

M-database-changes Metadata: This PR involves database schema changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] [Network Tokenization]: Tokenize before payment

6 participants