From b0cf19b88484132e54a10a969118f143f1fbc680 Mon Sep 17 00:00:00 2001 From: Kashif Date: Wed, 30 Oct 2024 15:30:20 +0530 Subject: [PATCH 1/9] feat(connector): [worldpay] use auto-capture by default and add dynamic fields --- crates/router/src/configs/defaults.rs | 286 ++++++++++++++---- .../router/src/connector/worldpay/requests.rs | 1 + .../src/connector/worldpay/transformers.rs | 20 +- 3 files changed, 240 insertions(+), 67 deletions(-) diff --git a/crates/router/src/configs/defaults.rs b/crates/router/src/configs/defaults.rs index c48d2fe54caa..5f6fbb849c75 100644 --- a/crates/router/src/configs/defaults.rs +++ b/crates/router/src/configs/defaults.rs @@ -199,7 +199,6 @@ impl Default for Mandates { enums::Connector::Adyen, enums::Connector::Authorizedotnet, enums::Connector::Globalpay, - enums::Connector::Worldpay, enums::Connector::Multisafepay, enums::Connector::Nexinets, enums::Connector::Noon, @@ -219,7 +218,6 @@ impl Default for Mandates { enums::Connector::Adyen, enums::Connector::Authorizedotnet, enums::Connector::Globalpay, - enums::Connector::Worldpay, enums::Connector::Multisafepay, enums::Connector::Nexinets, enums::Connector::Noon, @@ -3259,35 +3257,39 @@ impl Default for super::settings::RequiredFields { enums::Connector::Worldpay, RequiredFieldFinal { mandate: HashMap::new(), - non_mandate: HashMap::from([ - ( - "payment_method_data.card.card_number".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_number".to_string(), - display_name: "card_number".to_string(), - field_type: enums::FieldType::UserCardNumber, - value: None, - } - ), - ( - "payment_method_data.card.card_exp_month".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_exp_month".to_string(), - display_name: "card_exp_month".to_string(), - field_type: enums::FieldType::UserCardExpiryMonth, - value: None, - } - ), - ( - "payment_method_data.card.card_exp_year".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_exp_year".to_string(), - display_name: "card_exp_year".to_string(), - field_type: enums::FieldType::UserCardExpiryYear, - value: None, - } - ) - ]), + non_mandate: { + let mut pmd_fields = HashMap::from([ + ( + "payment_method_data.card.card_number".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_number".to_string(), + display_name: "card_number".to_string(), + field_type: enums::FieldType::UserCardNumber, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_month".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_month".to_string(), + display_name: "card_exp_month".to_string(), + field_type: enums::FieldType::UserCardExpiryMonth, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_year".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_year".to_string(), + display_name: "card_exp_year".to_string(), + field_type: enums::FieldType::UserCardExpiryYear, + value: None, + } + ) + ]); + pmd_fields.extend(get_worldpay_billing_required_fields()); + pmd_fields + }, common: HashMap::new(), } ), @@ -6447,35 +6449,39 @@ impl Default for super::settings::RequiredFields { enums::Connector::Worldpay, RequiredFieldFinal { mandate: HashMap::new(), - non_mandate: HashMap::from([ - ( - "payment_method_data.card.card_number".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_number".to_string(), - display_name: "card_number".to_string(), - field_type: enums::FieldType::UserCardNumber, - value: None, - } - ), - ( - "payment_method_data.card.card_exp_month".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_exp_month".to_string(), - display_name: "card_exp_month".to_string(), - field_type: enums::FieldType::UserCardExpiryMonth, - value: None, - } - ), - ( - "payment_method_data.card.card_exp_year".to_string(), - RequiredFieldInfo { - required_field: "payment_method_data.card.card_exp_year".to_string(), - display_name: "card_exp_year".to_string(), - field_type: enums::FieldType::UserCardExpiryYear, - value: None, - } - ) - ]), + non_mandate: { + let mut pmd_fields = HashMap::from([ + ( + "payment_method_data.card.card_number".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_number".to_string(), + display_name: "card_number".to_string(), + field_type: enums::FieldType::UserCardNumber, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_month".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_month".to_string(), + display_name: "card_exp_month".to_string(), + field_type: enums::FieldType::UserCardExpiryMonth, + value: None, + } + ), + ( + "payment_method_data.card.card_exp_year".to_string(), + RequiredFieldInfo { + required_field: "payment_method_data.card.card_exp_year".to_string(), + display_name: "card_exp_year".to_string(), + field_type: enums::FieldType::UserCardExpiryYear, + value: None, + } + ) + ]); + pmd_fields.extend(get_worldpay_billing_required_fields()); + pmd_fields + }, common: HashMap::new(), } ), @@ -12923,3 +12929,163 @@ pub fn get_shipping_required_fields() -> HashMap { ), ]) } + +pub fn get_worldpay_billing_required_fields() -> HashMap { + HashMap::from([ + ( + "billing.address.zip".to_string(), + RequiredFieldInfo { + required_field: "billing.address.zip".to_string(), + display_name: "zip".to_string(), + field_type: enums::FieldType::UserAddressPincode, + value: None, + }, + ), + ( + "billing.address.country".to_string(), + RequiredFieldInfo { + required_field: "billing.address.country".to_string(), + display_name: "country".to_string(), + field_type: enums::FieldType::UserAddressCountry { + options: vec![ + "AF".to_string(), + "AU".to_string(), + "AW".to_string(), + "AZ".to_string(), + "BS".to_string(), + "BH".to_string(), + "BD".to_string(), + "BB".to_string(), + "BZ".to_string(), + "BM".to_string(), + "BT".to_string(), + "BO".to_string(), + "BA".to_string(), + "BW".to_string(), + "BR".to_string(), + "BN".to_string(), + "BG".to_string(), + "BI".to_string(), + "KH".to_string(), + "CA".to_string(), + "CV".to_string(), + "KY".to_string(), + "CL".to_string(), + "CO".to_string(), + "KM".to_string(), + "CD".to_string(), + "CR".to_string(), + "CZ".to_string(), + "DZ".to_string(), + "DK".to_string(), + "DJ".to_string(), + "ST".to_string(), + "DO".to_string(), + "EC".to_string(), + "EG".to_string(), + "SV".to_string(), + "ER".to_string(), + "ET".to_string(), + "FK".to_string(), + "FJ".to_string(), + "GM".to_string(), + "GE".to_string(), + "GH".to_string(), + "GI".to_string(), + "GT".to_string(), + "GN".to_string(), + "GY".to_string(), + "HT".to_string(), + "HN".to_string(), + "HK".to_string(), + "HU".to_string(), + "IS".to_string(), + "IN".to_string(), + "ID".to_string(), + "IR".to_string(), + "IQ".to_string(), + "IE".to_string(), + "IL".to_string(), + "IT".to_string(), + "JM".to_string(), + "JP".to_string(), + "JO".to_string(), + "KZ".to_string(), + "KE".to_string(), + "KW".to_string(), + "LA".to_string(), + "LB".to_string(), + "LS".to_string(), + "LR".to_string(), + "LY".to_string(), + "LT".to_string(), + "MO".to_string(), + "MK".to_string(), + "MG".to_string(), + "MW".to_string(), + "MY".to_string(), + "MV".to_string(), + "MR".to_string(), + "MU".to_string(), + "MX".to_string(), + "MD".to_string(), + "MN".to_string(), + "MA".to_string(), + "MZ".to_string(), + "MM".to_string(), + "NA".to_string(), + "NZ".to_string(), + "NI".to_string(), + "NG".to_string(), + "KP".to_string(), + "NO".to_string(), + "AR".to_string(), + "PK".to_string(), + "PG".to_string(), + "PY".to_string(), + "PE".to_string(), + "UY".to_string(), + "PH".to_string(), + "PL".to_string(), + "GB".to_string(), + "QA".to_string(), + "OM".to_string(), + "RO".to_string(), + "RU".to_string(), + "RW".to_string(), + "WS".to_string(), + "SG".to_string(), + "ST".to_string(), + "ZA".to_string(), + "KR".to_string(), + "LK".to_string(), + "SH".to_string(), + "SD".to_string(), + "SR".to_string(), + "SZ".to_string(), + "SE".to_string(), + "CH".to_string(), + "SY".to_string(), + "TW".to_string(), + "TJ".to_string(), + "TZ".to_string(), + "TH".to_string(), + "TT".to_string(), + "TN".to_string(), + "TR".to_string(), + "UG".to_string(), + "UA".to_string(), + "US".to_string(), + "UZ".to_string(), + "VU".to_string(), + "VE".to_string(), + "VN".to_string(), + "ZM".to_string(), + "ZW".to_string(), + ], + }, + value: None, + }, + ), + ]) +} diff --git a/crates/router/src/connector/worldpay/requests.rs b/crates/router/src/connector/worldpay/requests.rs index b0fa85a64c36..b231ff354008 100644 --- a/crates/router/src/connector/worldpay/requests.rs +++ b/crates/router/src/connector/worldpay/requests.rs @@ -24,6 +24,7 @@ pub struct Merchant { #[derive(Clone, Debug, PartialEq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Instruction { + #[serde(skip_serializing_if = "Option::is_none")] pub settlement: Option, pub method: PaymentMethod, pub payment_instrument: PaymentInstrument, diff --git a/crates/router/src/connector/worldpay/transformers.rs b/crates/router/src/connector/worldpay/transformers.rs index efdd0fa68786..d3c59f75cede 100644 --- a/crates/router/src/connector/worldpay/transformers.rs +++ b/crates/router/src/connector/worldpay/transformers.rs @@ -280,13 +280,19 @@ impl }; Ok(Self { instruction: Instruction { - settlement: item - .router_data - .request - .capture_method - .map(|capture_method| AutoSettlement { - auto: capture_method == enums::CaptureMethod::Automatic, - }), + settlement: match ( + item.router_data.request.capture_method.unwrap_or_default(), + item.amount, + ) { + // Settlement field not allowed for zero amount + (_, 0) => None, + (enums::CaptureMethod::Automatic, _) => Some(AutoSettlement { auto: true }), + (enums::CaptureMethod::Manual, _) + | (enums::CaptureMethod::ManualMultiple, _) => { + Some(AutoSettlement { auto: false }) + } + _ => None, + }, method: PaymentMethod::try_from(( item.router_data.payment_method, item.router_data.request.payment_method_type, From 52e5f4dc5092b65e5eb3ea4bf909a2699e93c059 Mon Sep 17 00:00:00 2001 From: Kashif Date: Mon, 25 Nov 2024 15:30:23 +0530 Subject: [PATCH 2/9] refactor(connector): worldpay - update terminal status mapping for payments --- .../src/connectors/worldpay/transformers.rs | 15 ++++++++------- .../defaults/payment_connector_required_fields.rs | 2 ++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index b69e4bcd97b6..0b3e5b8c22a4 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -559,7 +559,7 @@ impl From for enums::AttemptStatus { fn from(item: PaymentOutcome) -> Self { match item { PaymentOutcome::Authorized => Self::Authorized, - PaymentOutcome::SentForSettlement => Self::CaptureInitiated, + PaymentOutcome::SentForSettlement => Self::Charged, PaymentOutcome::ThreeDsDeviceDataRequired => Self::DeviceDataCollectionPending, PaymentOutcome::ThreeDsAuthenticationFailed => Self::AuthenticationFailed, PaymentOutcome::ThreeDsChallenged => Self::AuthenticationPending, @@ -577,16 +577,17 @@ impl From<&EventType> for enums::AttemptStatus { fn from(value: &EventType) -> Self { match value { EventType::SentForAuthorization => Self::Authorizing, - EventType::SentForSettlement => Self::CaptureInitiated, + EventType::SentForSettlement => Self::Charged, EventType::Settled => Self::Charged, EventType::Authorized => Self::Authorized, - EventType::Refused | EventType::SettlementFailed => Self::Failure, - EventType::Cancelled - | EventType::SentForRefund + EventType::Refused + | EventType::SettlementFailed + | EventType::Expired + | EventType::Cancelled + | EventType::Error => Self::Failure, + EventType::SentForRefund | EventType::RefundFailed | EventType::Refunded - | EventType::Error - | EventType::Expired | EventType::Unknown => Self::Pending, } } diff --git a/crates/router/src/configs/defaults/payment_connector_required_fields.rs b/crates/router/src/configs/defaults/payment_connector_required_fields.rs index e14fe6eb6b3d..e2756726d1d1 100644 --- a/crates/router/src/configs/defaults/payment_connector_required_fields.rs +++ b/crates/router/src/configs/defaults/payment_connector_required_fields.rs @@ -66,6 +66,7 @@ impl Default for Mandates { enums::Connector::Adyen, enums::Connector::Authorizedotnet, enums::Connector::Globalpay, + enums::Connector::Worldpay, enums::Connector::Multisafepay, enums::Connector::Nexinets, enums::Connector::Noon, @@ -86,6 +87,7 @@ impl Default for Mandates { enums::Connector::Adyen, enums::Connector::Authorizedotnet, enums::Connector::Globalpay, + enums::Connector::Worldpay, enums::Connector::Multisafepay, enums::Connector::Nexinets, enums::Connector::Noon, From 2dc8e3f6285d26cf1b2aa258e2b12c6038d3665a Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 15:52:07 +0530 Subject: [PATCH 3/9] refactor: update refunds flow and fix cypress test cases for worldpay --- .../src/connectors/worldpay.rs | 4 +- .../src/connectors/worldpay/transformers.rs | 17 + crates/router/src/core/refunds.rs | 6 +- .../cypress/e2e/PaymentUtils/WorldPay.js | 336 +++++++++++++++--- .../cypress/fixtures/confirm-body.json | 2 +- .../cypress/fixtures/create-confirm-body.json | 2 +- .../cypress/fixtures/create-mandate-cit.json | 2 +- .../cypress/fixtures/create-mandate-mit.json | 2 +- .../cypress/fixtures/create-pm-id-mit.json | 2 +- .../fixtures/save-card-confirm-body.json | 2 +- 10 files changed, 307 insertions(+), 68 deletions(-) diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs index fd67bb60128a..920e4f16bfd2 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay.rs @@ -617,7 +617,7 @@ impl ConnectorIntegration fo .map(|id| id.to_string()) }); Ok(PaymentsCaptureRouterData { - status: enums::AttemptStatus::Pending, + status: enums::AttemptStatus::Charged, response: Ok(PaymentsResponseData::TransactionResponse { resource_id: ResponseId::foreign_try_from(( response, @@ -967,12 +967,12 @@ impl ConnectorIntegration for Worldpa }); Ok(RefundExecuteRouterData { response: Ok(RefundsResponseData { + refund_status: enums::RefundStatus::from(response.outcome.clone()), connector_refund_id: ResponseIdStr::foreign_try_from(( response, optional_correlation_id, ))? .id, - refund_status: enums::RefundStatus::Pending, }), ..data.clone() }) diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs index e8e5ac01009f..8ecc3ad792ce 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -574,6 +574,23 @@ impl From for enums::AttemptStatus { } } +impl From for enums::RefundStatus { + fn from(item: PaymentOutcome) -> Self { + match item { + PaymentOutcome::SentForPartialRefund | PaymentOutcome::SentForRefund => Self::Success, + PaymentOutcome::Refused + | PaymentOutcome::FraudHighRisk + | PaymentOutcome::Authorized + | PaymentOutcome::SentForSettlement + | PaymentOutcome::ThreeDsDeviceDataRequired + | PaymentOutcome::ThreeDsAuthenticationFailed + | PaymentOutcome::ThreeDsChallenged + | PaymentOutcome::SentForCancellation + | PaymentOutcome::ThreeDsUnavailable => Self::Failure, + } + } +} + impl From<&EventType> for enums::AttemptStatus { fn from(value: &EventType) -> Self { match value { diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index c3e49a49bb14..2fd5d59def9e 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use api_models::admin::MerchantConnectorInfo; use common_utils::{ ext_traits::{AsyncExt, ValueExt}, - types::{ConnectorTransactionId, ConnectorTransactionIdTrait, MinorUnit}, + types::{ConnectorTransactionId, MinorUnit}, }; use diesel_models::process_tracker::business_status; use error_stack::{report, ResultExt}; @@ -446,7 +446,7 @@ pub async fn refund_retrieve_core( let payment_attempt = db .find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( - refund.get_connector_transaction_id(), + refund.connector_transaction_id.get_id(), payment_id, merchant_id, merchant_account.storage_scheme, @@ -1451,7 +1451,7 @@ pub async fn trigger_refund_execute_workflow( let payment_attempt = db .find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( - refund.get_connector_transaction_id(), + &refund.connector_transaction_id.get_id(), &refund_core.payment_id, &refund.merchant_id, merchant_account.storage_scheme, diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index 5b950219fb25..3f72d676c612 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -102,7 +102,8 @@ export const connectorDetails = { currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", - }, Response: { + }, + Response: { status: 200, body: { status: "requires_payment_method", @@ -127,7 +128,7 @@ export const connectorDetails = { body: { status: "requires_capture", payment_method: "card", - payment_method_type: "debit", + payment_method_type: "credit", attempt_count: 1, payment_method_data: paymentMethodDataNoThreeDsResponse, }, @@ -147,9 +148,9 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing", + status: "succeeded", payment_method: "card", - payment_method_type: "debit", + payment_method_type: "credit", attempt_count: 1, payment_method_data: paymentMethodDataNoThreeDsResponse, }, @@ -168,9 +169,9 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing", + status: "succeeded", amount: 6500, - amount_capturable: 6500, + amount_capturable: 0, }, }, }, @@ -187,9 +188,9 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing", + status: "partially_captured", amount: 6500, - amount_capturable: 6500, + amount_capturable: 0, }, }, }, @@ -236,13 +237,42 @@ export const connectorDetails = { }, }, Response: { - status: 400, body: { - error: { - type: "invalid_request", - message: "Missing required param: payment_method_data", - code: "IR_04" - } + status: "requires_capture", + }, + }, + }, + SaveCardUseNo3DSManualCaptureOffSession: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + setup_future_usage: "off_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + SaveCardConfirmManualCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, }, }, @@ -267,10 +297,45 @@ export const connectorDetails = { Response: { status: 200, body: { - status: "processing" + status: "succeeded" }, } }, + SaveCardUseNo3DSAutoCaptureOffSession: { + Request: { + payment_method: "card", + payment_method_type: "debit", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + setup_future_usage: "off_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + SaveCardConfirmAutoCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, "3DSManualCapture": { Request: { payment_method: "card", @@ -313,10 +378,6 @@ export const connectorDetails = { }, }, }, - - /** - * Variation cases - */ CaptureCapturedAmount: { Request: { Request: { @@ -334,7 +395,7 @@ export const connectorDetails = { error: { type: "invalid_request", message: - "This Payment could not be captured because it has a capture_method of automatic. The expected state is manual_multiple", + "This Payment could not be captured because it has a payment.status of succeeded. The expected state is requires_capture, partially_captured_and_capturable, processing", code: "IR_14", }, }, @@ -355,37 +416,17 @@ export const connectorDetails = { error: { type: "invalid_request", message: - "You cannot confirm this payment because it has status processing", + "You cannot confirm this payment because it has status succeeded", code: "IR_16", }, }, }, }, - - /** - * Not implemented or not ready for running test cases - * - Refunds - * - Mandates - */ Refund: { Request: {}, Response: { body: { - error: { - type: "invalid_request", - message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", - code: "IR_14" - } - } - }, - ResponseCustom: { - status: 400, - body: { - error: { - type: "invalid_request", - message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", - code: "IR_14", - }, + status: "succeeded" }, }, }, @@ -393,11 +434,35 @@ export const connectorDetails = { Request: {}, Response: { body: { - error: { - type: "invalid_request", - message: "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", - code: "IR_14" - } + status: "succeeded" + } + } + }, + manualPaymentRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + }, + Response: { + body: { + status: "succeeded" + } + } + }, + manualPaymentPartialRefund: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + }, + Response: { + body: { + status: "succeeded" } } }, @@ -405,14 +470,74 @@ export const connectorDetails = { Request: {}, Response: { body: { - error: { - type: "invalid_request", - message: "Refund does not exist in our records.", - code: "HE_02" - } + status: "succeeded" } } }, + MandateSingleUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateSingleUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + MandateMultiUseNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateMultiUseNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, ZeroAuthMandate: { Request: { payment_method: "card", @@ -423,12 +548,109 @@ export const connectorDetails = { mandate_data: singleUseMandateData, }, Response: { + status: 200, body: { - error: { - type: "invalid_request", - message: "Setup Mandate flow for Worldpay is not implemented", - code: "IR_00" - } + error_code: "internalErrorOccurred", + error_message: "We cannot currently process your request. Please contact support.", + status: "failed", + payment_method_id: null + }, + }, + }, + PaymentMethodIdMandateNo3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: null, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + PaymentMethodIdMandateNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: null, + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + PaymentMethodIdMandate3DSAutoCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDsTestCardDetailsRequest, + }, + currency: "USD", + mandate_data: null, + authentication_type: "three_ds", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + PaymentMethodIdMandate3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulThreeDsTestCardDetailsRequest, + }, + mandate_data: null, + authentication_type: "three_ds", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", }, }, }, diff --git a/cypress-tests/cypress/fixtures/confirm-body.json b/cypress-tests/cypress/fixtures/confirm-body.json index fa4769b627f4..d92be2d91e7c 100644 --- a/cypress-tests/cypress/fixtures/confirm-body.json +++ b/cypress-tests/cypress/fixtures/confirm-body.json @@ -29,7 +29,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, diff --git a/cypress-tests/cypress/fixtures/create-confirm-body.json b/cypress-tests/cypress/fixtures/create-confirm-body.json index a779557ed5e7..2a9e8b19ee12 100644 --- a/cypress-tests/cypress/fixtures/create-confirm-body.json +++ b/cypress-tests/cypress/fixtures/create-confirm-body.json @@ -70,7 +70,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, diff --git a/cypress-tests/cypress/fixtures/create-mandate-cit.json b/cypress-tests/cypress/fixtures/create-mandate-cit.json index c96284ea99ba..d33cb8b91c7f 100644 --- a/cypress-tests/cypress/fixtures/create-mandate-cit.json +++ b/cypress-tests/cypress/fixtures/create-mandate-cit.json @@ -80,7 +80,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, diff --git a/cypress-tests/cypress/fixtures/create-mandate-mit.json b/cypress-tests/cypress/fixtures/create-mandate-mit.json index 9612eac32091..7b70279979aa 100644 --- a/cypress-tests/cypress/fixtures/create-mandate-mit.json +++ b/cypress-tests/cypress/fixtures/create-mandate-mit.json @@ -26,7 +26,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, diff --git a/cypress-tests/cypress/fixtures/create-pm-id-mit.json b/cypress-tests/cypress/fixtures/create-pm-id-mit.json index c78cf2a74c5a..77d3c76b8b22 100644 --- a/cypress-tests/cypress/fixtures/create-pm-id-mit.json +++ b/cypress-tests/cypress/fixtures/create-pm-id-mit.json @@ -31,7 +31,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, diff --git a/cypress-tests/cypress/fixtures/save-card-confirm-body.json b/cypress-tests/cypress/fixtures/save-card-confirm-body.json index 17a860fd1885..615cec8abf72 100644 --- a/cypress-tests/cypress/fixtures/save-card-confirm-body.json +++ b/cypress-tests/cypress/fixtures/save-card-confirm-body.json @@ -32,7 +32,7 @@ "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "en-US", - "color_depth": 30, + "color_depth": 32, "screen_height": 1117, "screen_width": 1728, "time_zone": -330, From a3daab7c20bae1a9405aaf5e2a185357d139f02d Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 16:21:23 +0530 Subject: [PATCH 4/9] chore: update test cases --- .../cypress/e2e/PaymentUtils/WorldPay.js | 91 ++++--------------- 1 file changed, 18 insertions(+), 73 deletions(-) diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index 3f72d676c612..f83f70946db3 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -78,15 +78,17 @@ const payment_method_data_3ds = { billing: null }; -const singleUseMandateData = { - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, +const offileCustomerAcceptance = { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "125.0.0.1", + user_agent: "amet irure esse", }, +}; + +const singleUseMandateData = { + customer_acceptance: offileCustomerAcceptance, mandate_type: { single_use: { amount: 8000, @@ -227,14 +229,7 @@ export const connectorDetails = { }, currency: "USD", setup_future_usage: "on_session", - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "127.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { body: { @@ -249,14 +244,7 @@ export const connectorDetails = { card: successfulNoThreeDsCardDetailsRequest, }, setup_future_usage: "off_session", - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "127.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -285,14 +273,7 @@ export const connectorDetails = { currency: "USD", setup_future_usage: "on_session", browser_info, - 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", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -309,14 +290,7 @@ export const connectorDetails = { card: successfulNoThreeDsCardDetailsRequest, }, setup_future_usage: "off_session", - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "127.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -407,7 +381,6 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, }, Response: { @@ -565,14 +538,7 @@ export const connectorDetails = { }, currency: "USD", mandate_data: null, - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -589,14 +555,7 @@ export const connectorDetails = { }, currency: "USD", mandate_data: null, - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -614,14 +573,7 @@ export const connectorDetails = { currency: "USD", mandate_data: null, authentication_type: "three_ds", - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, @@ -638,14 +590,7 @@ export const connectorDetails = { }, mandate_data: null, authentication_type: "three_ds", - customer_acceptance: { - acceptance_type: "offline", - accepted_at: "1963-05-03T04:07:52.723Z", - online: { - ip_address: "125.0.0.1", - user_agent: "amet irure esse", - }, - }, + customer_acceptance: offileCustomerAcceptance, }, Response: { status: 200, From f2e94a8551696b2c8647c3e17e2547c73e4c6dbb Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 16:24:30 +0530 Subject: [PATCH 5/9] chore: remove currency from confirm calls --- cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index f83f70946db3..9c363687eb71 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -120,7 +120,6 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", billing: billing, @@ -143,7 +142,6 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", }, @@ -317,7 +315,6 @@ export const connectorDetails = { payment_method_data: { card: successfulThreeDsTestCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", browser_info, From eaad8bcb66ac4fbb0f4ae4a845566520577c7dbf Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 17:28:19 +0530 Subject: [PATCH 6/9] chore: update test cases --- .../cypress/e2e/PaymentUtils/WorldPay.js | 35 +++++++++++++++++++ cypress-tests/cypress/support/commands.js | 24 +++++++------ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index 9c363687eb71..d45458369c59 100644 --- a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js +++ b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js @@ -518,6 +518,41 @@ export const connectorDetails = { mandate_data: singleUseMandateData, }, Response: { + trigger_skip: true, + status: 200, + body: { + error_code: "internalErrorOccurred", + error_message: "We cannot currently process your request. Please contact support.", + status: "failed", + payment_method_id: null + }, + }, + }, + ZeroAuthPaymentIntent: { + Request: { + amount: 0, + setup_future_usage: "off_session", + currency: "USD", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + setup_future_usage: "off_session", + }, + }, + }, + ZeroAuthConfirmPayment: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: singleUseMandateData, + }, + Response: { + trigger_skip: true, status: 200, body: { error_code: "internalErrorOccurred", diff --git a/cypress-tests/cypress/support/commands.js b/cypress-tests/cypress/support/commands.js index 48a62fb4388b..6efb63e47350 100644 --- a/cypress-tests/cypress/support/commands.js +++ b/cypress-tests/cypress/support/commands.js @@ -1732,13 +1732,13 @@ Cypress.Commands.add( for (const key in response.body.attempts) { if ( response.body.attempts[key].attempt_id === - `${payment_id}_${attempt}` && + `${payment_id}_${attempt}` && response.body.status === "succeeded" ) { expect(response.body.attempts[key].status).to.equal("charged"); } else if ( response.body.attempts[key].attempt_id === - `${payment_id}_${attempt}` && + `${payment_id}_${attempt}` && response.body.status === "requires_customer_action" ) { expect(response.body.attempts[key].status).to.equal( @@ -1854,8 +1854,10 @@ Cypress.Commands.add( ); 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.status !== "failed") { + expect(response.body.payment_method_id, "payment_method_id").to.not.be + .null; + } if (requestBody.mandate_data === null) { expect(response.body).to.have.property("payment_method_id"); @@ -1969,7 +1971,7 @@ Cypress.Commands.add( } else if (response.body.authentication_type === "no_three_ds") { if (response.body.connector === "fiuu") { expect(response.body.status).to.equal("failed"); - } + } } else { throw new Error( `Invalid authentication type ${response.body.authentication_type}` @@ -2049,7 +2051,7 @@ Cypress.Commands.add( } else if (response.body.authentication_type === "no_three_ds") { if (response.body.connector === "fiuu") { expect(response.body.status).to.equal("failed"); - } + } } else { throw new Error( `Invalid authentication type ${response.body.authentication_type}` @@ -2098,11 +2100,11 @@ Cypress.Commands.add( if (globalState.get("connectorId") !== "cybersource") { return; } - + const apiKey = globalState.get("apiKey"); const baseUrl = globalState.get("baseUrl"); const url = `${baseUrl}/payments`; - + cy.request({ method: "POST", url: url, @@ -2114,7 +2116,7 @@ Cypress.Commands.add( body: requestBody, }).then((response) => { logRequestId(response.headers["x-request-id"]); - + if (response.status === 200) { expect(response.headers["content-type"]).to.include("application/json"); @@ -2128,7 +2130,7 @@ Cypress.Commands.add( const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); } else if (response.body.authentication_type === "no_three_ds") { - expect(response.body.status).to.equal("succeeded"); + expect(response.body.status).to.equal("succeeded"); } else { throw new Error( `Invalid authentication type ${response.body.authentication_type}` @@ -2142,7 +2144,7 @@ Cypress.Commands.add( const nextActionUrl = response.body.next_action.redirect_to_url; cy.log(nextActionUrl); } else if (response.body.authentication_type === "no_three_ds") { - expect(response.body.status).to.equal("requires_capture"); + expect(response.body.status).to.equal("requires_capture"); } else { throw new Error( `Invalid authentication type ${response.body.authentication_type}` From 05a89c491322f0394f8fe13eae793bbe25982ec6 Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 17:53:12 +0530 Subject: [PATCH 7/9] chore: clippy fixes --- crates/router/src/core/refunds.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 2fd5d59def9e..90f153cbb6c5 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -1451,7 +1451,7 @@ pub async fn trigger_refund_execute_workflow( let payment_attempt = db .find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( - &refund.connector_transaction_id.get_id(), + refund.connector_transaction_id.get_id(), &refund_core.payment_id, &refund.merchant_id, merchant_account.storage_scheme, From 26b3737a7b34c83932a853f2cb4d99131439dacc Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 18:17:32 +0530 Subject: [PATCH 8/9] refactor: update status mapping --- crates/hyperswitch_connectors/src/connectors/worldpay.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/hyperswitch_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs index 920e4f16bfd2..be8f9bca3527 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay.rs @@ -617,7 +617,7 @@ impl ConnectorIntegration fo .map(|id| id.to_string()) }); Ok(PaymentsCaptureRouterData { - status: enums::AttemptStatus::Charged, + status: enums::AttemptStatus::from(response.outcome.clone()), response: Ok(PaymentsResponseData::TransactionResponse { resource_id: ResponseId::foreign_try_from(( response, From 9b7828e05a1f733ed231c93e4024d24d7d09647d Mon Sep 17 00:00:00 2001 From: Kashif Date: Tue, 26 Nov 2024 21:08:39 +0530 Subject: [PATCH 9/9] refactor(core): use ConnectorTransactionId for find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id query --- crates/diesel_models/src/query/payment_attempt.rs | 4 ++-- .../src/payments/payment_attempt.rs | 2 +- crates/router/src/core/refunds.rs | 4 ++-- crates/router/src/db/kafka_store.rs | 2 +- crates/storage_impl/src/mock_db/payment_attempt.rs | 2 +- crates/storage_impl/src/payments/payment_attempt.rs | 9 +++++---- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/crates/diesel_models/src/query/payment_attempt.rs b/crates/diesel_models/src/query/payment_attempt.rs index 46a84488898b..9dd13e5b0300 100644 --- a/crates/diesel_models/src/query/payment_attempt.rs +++ b/crates/diesel_models/src/query/payment_attempt.rs @@ -97,14 +97,14 @@ impl PaymentAttempt { #[cfg(feature = "v1")] pub async fn find_by_connector_transaction_id_payment_id_merchant_id( conn: &PgPooledConn, - connector_transaction_id: &str, + connector_transaction_id: &common_utils::types::ConnectorTransactionId, payment_id: &common_utils::id_type::PaymentId, merchant_id: &common_utils::id_type::MerchantId, ) -> StorageResult { generics::generic_find_one::<::Table, _, _>( conn, dsl::connector_transaction_id - .eq(connector_transaction_id.to_owned()) + .eq(connector_transaction_id.get_id().to_owned()) .and(dsl::payment_id.eq(payment_id.to_owned())) .and(dsl::merchant_id.eq(merchant_id.to_owned())), ) diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index 4ca6084c958f..289b1bab37df 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -81,7 +81,7 @@ pub trait PaymentAttemptInterface { #[cfg(feature = "v1")] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, - connector_transaction_id: &str, + connector_transaction_id: &ConnectorTransactionId, payment_id: &id_type::PaymentId, merchant_id: &id_type::MerchantId, storage_scheme: storage_enums::MerchantStorageScheme, diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index 90f153cbb6c5..c706d8854af5 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -446,7 +446,7 @@ pub async fn refund_retrieve_core( let payment_attempt = db .find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( - refund.connector_transaction_id.get_id(), + &refund.connector_transaction_id, payment_id, merchant_id, merchant_account.storage_scheme, @@ -1451,7 +1451,7 @@ pub async fn trigger_refund_execute_workflow( let payment_attempt = db .find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( - refund.connector_transaction_id.get_id(), + &refund.connector_transaction_id, &refund_core.payment_id, &refund.merchant_id, merchant_account.storage_scheme, diff --git a/crates/router/src/db/kafka_store.rs b/crates/router/src/db/kafka_store.rs index a9df1abbc083..e37ff3aa1678 100644 --- a/crates/router/src/db/kafka_store.rs +++ b/crates/router/src/db/kafka_store.rs @@ -1454,7 +1454,7 @@ impl PaymentAttemptInterface for KafkaStore { #[cfg(feature = "v1")] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, - connector_transaction_id: &str, + connector_transaction_id: &common_utils::types::ConnectorTransactionId, payment_id: &id_type::PaymentId, merchant_id: &id_type::MerchantId, storage_scheme: MerchantStorageScheme, diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs index 83691f46129b..0415625f7ebb 100644 --- a/crates/storage_impl/src/mock_db/payment_attempt.rs +++ b/crates/storage_impl/src/mock_db/payment_attempt.rs @@ -254,7 +254,7 @@ impl PaymentAttemptInterface for MockDb { #[cfg(feature = "v1")] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, - _connector_transaction_id: &str, + _connector_transaction_id: &common_utils::types::ConnectorTransactionId, _payment_id: &common_utils::id_type::PaymentId, _merchant_id: &common_utils::id_type::MerchantId, _storage_scheme: storage_enums::MerchantStorageScheme, diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs index 9b9121952b16..4eedfd5005e6 100644 --- a/crates/storage_impl/src/payments/payment_attempt.rs +++ b/crates/storage_impl/src/payments/payment_attempt.rs @@ -151,7 +151,7 @@ impl PaymentAttemptInterface for RouterStore { #[instrument(skip_all)] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, - connector_transaction_id: &str, + connector_transaction_id: &ConnectorTransactionId, payment_id: &common_utils::id_type::PaymentId, merchant_id: &common_utils::id_type::MerchantId, _storage_scheme: MerchantStorageScheme, @@ -786,7 +786,7 @@ impl PaymentAttemptInterface for KVRouterStore { #[instrument(skip_all)] async fn find_payment_attempt_by_connector_transaction_id_payment_id_merchant_id( &self, - connector_transaction_id: &str, + connector_transaction_id: &ConnectorTransactionId, payment_id: &common_utils::id_type::PaymentId, merchant_id: &common_utils::id_type::MerchantId, storage_scheme: MerchantStorageScheme, @@ -811,8 +811,9 @@ impl PaymentAttemptInterface for KVRouterStore { MerchantStorageScheme::RedisKv => { // We assume that PaymentAttempt <=> PaymentIntent is a one-to-one relation for now let lookup_id = format!( - "pa_conn_trans_{}_{connector_transaction_id}", - merchant_id.get_string_repr() + "pa_conn_trans_{}_{}", + merchant_id.get_string_repr(), + connector_transaction_id.get_id() ); let lookup = fallback_reverse_lookup_not_found!( self.get_lookup_by_lookup_id(&lookup_id, storage_scheme)