From 107098cda45440f9d80c6305b7b6e5cd3de9ca0d Mon Sep 17 00:00:00 2001 From: DEEPANSHU BANSAL <41580413+deepanshu-iiitu@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:20:46 +0530 Subject: [PATCH 1/3] fix(core): Populate off_session based on payments request (#6855) --- crates/router/src/core/payments/transformers.rs | 15 ++++++++++++--- cypress-tests/cypress/e2e/PaymentUtils/Stripe.js | 12 +++--------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 48e931989f02..85bc51a09a7f 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -2615,7 +2615,10 @@ impl TryFrom> for types::PaymentsAuthoriz payment_method_data: (payment_method_data.get_required_value("payment_method_data")?), setup_future_usage: payment_data.payment_intent.setup_future_usage, mandate_id: payment_data.mandate_id.clone(), - off_session: payment_data.mandate_id.as_ref().map(|_| true), + off_session: payment_data + .mandate_id + .as_ref() + .and(payment_data.payment_intent.off_session), setup_mandate_details: payment_data.setup_mandate.clone(), confirm: payment_data.payment_attempt.confirm, statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, @@ -3218,7 +3221,10 @@ impl TryFrom> for types::SetupMandateRequ .get_required_value("payment_method_data")?), statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, setup_future_usage: payment_data.payment_intent.setup_future_usage, - off_session: payment_data.mandate_id.as_ref().map(|_| true), + off_session: payment_data + .mandate_id + .as_ref() + .and(payment_data.payment_intent.off_session), mandate_id: payment_data.mandate_id.clone(), setup_mandate_details: payment_data.setup_mandate, customer_acceptance: payment_data.customer_acceptance, @@ -3333,7 +3339,10 @@ impl TryFrom> for types::CompleteAuthoriz Ok(Self { setup_future_usage: payment_data.payment_intent.setup_future_usage, mandate_id: payment_data.mandate_id.clone(), - off_session: payment_data.mandate_id.as_ref().map(|_| true), + off_session: payment_data + .mandate_id + .as_ref() + .and(payment_data.payment_intent.off_session), setup_mandate_details: payment_data.setup_mandate.clone(), confirm: payment_data.payment_attempt.confirm, statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js b/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js index fdc1926ae077..d75fcf6877b9 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/Stripe.js @@ -721,9 +721,7 @@ export const connectorDetails = { Response: { status: 200, body: { - error_code: "No error code", - error_message: - "You cannot confirm with `off_session=true` when `setup_future_usage` is also set on the PaymentIntent. The customer needs to be on-session to perform the steps which may be required to set up the PaymentMethod for future usage. Please confirm this PaymentIntent with your customer on-session.", + status: "succeeded", }, }, }, @@ -734,9 +732,7 @@ export const connectorDetails = { Response: { status: 200, body: { - error_code: "No error code", - error_message: - "You cannot confirm with `off_session=true` when `setup_future_usage` is also set on the PaymentIntent. The customer needs to be on-session to perform the steps which may be required to set up the PaymentMethod for future usage. Please confirm this PaymentIntent with your customer on-session.", + status: "requires_capture", }, }, }, @@ -748,9 +744,7 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "failed", - error_message: - "You cannot confirm with `off_session=true` when `setup_future_usage` is also set on the PaymentIntent. The customer needs to be on-session to perform the steps which may be required to set up the PaymentMethod for future usage. Please confirm this PaymentIntent with your customer on-session.", + status: "succeeded", }, }, }, From 5c4de8a5133c9a835d8c706c9b71bdfc8140568d Mon Sep 17 00:00:00 2001 From: Sakil Mostak <73734619+Sakilmostak@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:19:56 +0530 Subject: [PATCH 2/3] fix(payment_methods): card_network and card_scheme should be consistent (#6849) --- crates/diesel_models/src/payment_method.rs | 18 +++++++++++++++++- .../router/src/core/payment_methods/cards.rs | 2 ++ .../router/src/core/payments/tokenization.rs | 10 +++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/crates/diesel_models/src/payment_method.rs b/crates/diesel_models/src/payment_method.rs index 46af78d6d91e..8ae34a6f89cf 100644 --- a/crates/diesel_models/src/payment_method.rs +++ b/crates/diesel_models/src/payment_method.rs @@ -219,6 +219,7 @@ pub enum PaymentMethodUpdate { }, UpdatePaymentMethodDataAndLastUsed { payment_method_data: Option, + scheme: Option, last_used_at: PrimitiveDateTime, }, PaymentMethodDataUpdate { @@ -264,6 +265,7 @@ pub enum PaymentMethodUpdate { pub enum PaymentMethodUpdate { UpdatePaymentMethodDataAndLastUsed { payment_method_data: Option, + scheme: Option, last_used_at: PrimitiveDateTime, }, PaymentMethodDataUpdate { @@ -395,6 +397,7 @@ pub struct PaymentMethodUpdateInternal { last_modified: PrimitiveDateTime, network_token_locker_id: Option, network_token_payment_method_data: Option, + scheme: Option, } #[cfg(all( @@ -419,6 +422,7 @@ impl PaymentMethodUpdateInternal { last_modified, network_token_locker_id, network_token_payment_method_data, + scheme, } = self; PaymentMethod { @@ -426,7 +430,7 @@ impl PaymentMethodUpdateInternal { merchant_id: source.merchant_id, payment_method_id: source.payment_method_id, accepted_currency: source.accepted_currency, - scheme: source.scheme, + scheme: scheme.or(source.scheme), token: source.token, cardholder_name: source.cardholder_name, issuer_name: source.issuer_name, @@ -489,6 +493,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::PaymentMethodDataUpdate { payment_method_data, @@ -508,6 +513,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::LastUsedUpdate { last_used_at } => Self { metadata: None, @@ -525,9 +531,11 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed { payment_method_data, + scheme, last_used_at, } => Self { metadata: None, @@ -545,6 +553,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme, }, PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate { network_transaction_id, @@ -565,6 +574,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::StatusUpdate { status } => Self { metadata: None, @@ -582,6 +592,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::AdditionalDataUpdate { payment_method_data, @@ -609,6 +620,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id, network_token_payment_method_data, + scheme: None, }, PaymentMethodUpdate::ConnectorMandateDetailsUpdate { connector_mandate_details, @@ -628,6 +640,7 @@ impl From for PaymentMethodUpdateInternal { last_modified: common_utils::date_time::now(), network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, PaymentMethodUpdate::NetworkTokenDataUpdate { network_token_requestor_reference_id, @@ -649,6 +662,7 @@ impl From for PaymentMethodUpdateInternal { network_token_requestor_reference_id, network_token_locker_id, network_token_payment_method_data, + scheme: None, }, PaymentMethodUpdate::ConnectorNetworkTransactionIdAndMandateDetailsUpdate { connector_mandate_details, @@ -670,6 +684,7 @@ impl From for PaymentMethodUpdateInternal { network_token_requestor_reference_id: None, network_token_locker_id: None, network_token_payment_method_data: None, + scheme: None, }, } } @@ -714,6 +729,7 @@ impl From for PaymentMethodUpdateInternal { PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed { payment_method_data, last_used_at, + .. } => Self { payment_method_data, last_used_at: Some(last_used_at), diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs index 9d8fbf58f5e7..e5e9ff92657a 100644 --- a/crates/router/src/core/payment_methods/cards.rs +++ b/crates/router/src/core/payment_methods/cards.rs @@ -2800,9 +2800,11 @@ pub async fn update_payment_method_and_last_used( pm: domain::PaymentMethod, payment_method_update: Option, storage_scheme: MerchantStorageScheme, + card_scheme: Option, ) -> errors::CustomResult<(), errors::VaultError> { let pm_update = payment_method::PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed { payment_method_data: payment_method_update, + scheme: card_scheme, last_used_at: common_utils::date_time::now(), }; db.update_payment_method(&(state.into()), key_store, pm, pm_update, storage_scheme) diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs index 89fb7752d1b0..94f221dd722f 100644 --- a/crates/router/src/core/payments/tokenization.rs +++ b/crates/router/src/core/payments/tokenization.rs @@ -549,8 +549,15 @@ where let existing_pm_data = payment_methods::cards::get_card_details_without_locker_fallback(&existing_pm,state) .await?; + // scheme should be updated in case of co-badged cards + let card_scheme = card + .card_network + .clone() + .map(|card_network| card_network.to_string()) + .or(existing_pm_data.scheme.clone()); + let updated_card = Some(CardDetailFromLocker { - scheme: existing_pm.scheme.clone(), + scheme: card_scheme.clone(), last4_digits: Some(card.card_number.get_last4()), issuer_country: card .card_issuing_country @@ -596,6 +603,7 @@ where existing_pm, pm_data_encrypted.map(Into::into), merchant_account.storage_scheme, + card_scheme, ) .await .change_context(errors::ApiErrorResponse::InternalServerError) From 653fd0e2464d71b2101c8e88eed458d96ae15c50 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:21:46 +0000 Subject: [PATCH 3/3] chore(version): 2024.12.18.0 --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11293a2f7e90..9cb67d8929e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,35 @@ All notable changes to HyperSwitch will be documented here. - - - +## 2024.12.18.0 + +### Features + +- **analytics:** Analytics Request Validator and config driven forex feature ([#6733](https://github.com/juspay/hyperswitch/pull/6733)) ([`c883aa5`](https://github.com/juspay/hyperswitch/commit/c883aa59aae4ddbcf8c754052ed60b4514043d47)) +- **redis-interface:** Add redis interface command to set multiple the keys in redis and increment if the key already exists ([#6827](https://github.com/juspay/hyperswitch/pull/6827)) ([`94ad90f`](https://github.com/juspay/hyperswitch/commit/94ad90f9ed8b2d8a0e4715875f3fdccf2abec15d)) + +### Bug Fixes + +- **connector:** + - 5xx error for Volt Payment Sync ([#6846](https://github.com/juspay/hyperswitch/pull/6846)) ([`588ce40`](https://github.com/juspay/hyperswitch/commit/588ce408b4b04bdd89f2594239e7efc9e0f66114)) + - Add expiry year conversion for adyen mit transactions ([#6851](https://github.com/juspay/hyperswitch/pull/6851)) ([`c154a38`](https://github.com/juspay/hyperswitch/commit/c154a385597104fcdbed4aa859c52c97a240c39f)) +- **core:** Populate off_session based on payments request ([#6855](https://github.com/juspay/hyperswitch/pull/6855)) ([`107098c`](https://github.com/juspay/hyperswitch/commit/107098cda45440f9d80c6305b7b6e5cd3de9ca0d)) +- **payment_methods:** Card_network and card_scheme should be consistent ([#6849](https://github.com/juspay/hyperswitch/pull/6849)) ([`5c4de8a`](https://github.com/juspay/hyperswitch/commit/5c4de8a5133c9a835d8c706c9b71bdfc8140568d)) + +### Refactors + +- **constraint_graph:** Handle PML for cases where setup_future_usage is not passed in payments ([#6810](https://github.com/juspay/hyperswitch/pull/6810)) ([`e8bfd0e`](https://github.com/juspay/hyperswitch/commit/e8bfd0e2270300fff3f051143f34ebb782da5366)) +- **customers_v2:** Address panics and some bugs in customers v2 endpoints ([#6836](https://github.com/juspay/hyperswitch/pull/6836)) ([`dfbfce4`](https://github.com/juspay/hyperswitch/commit/dfbfce4e4247166e43f1a805e65331b21eab4e09)) + +### Miscellaneous Tasks + +- **analytics:** SDK table schema changes ([#6579](https://github.com/juspay/hyperswitch/pull/6579)) ([`a056dc7`](https://github.com/juspay/hyperswitch/commit/a056dc72db23200c473e8aa2ec8ce5579fa4f6c6)) +- **wasm:** Add wasm changes for ctp_mastercard connector ([#6838](https://github.com/juspay/hyperswitch/pull/6838)) ([`b301d09`](https://github.com/juspay/hyperswitch/commit/b301d09213a8c1c68d711a3b34227d13e61e52f9)) + +**Full Changelog:** [`2024.12.17.0...2024.12.18.0`](https://github.com/juspay/hyperswitch/compare/2024.12.17.0...2024.12.18.0) + +- - - + ## 2024.12.17.0 ### Features