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_connectors/src/connectors/worldpay.rs b/crates/hyperswitch_connectors/src/connectors/worldpay.rs index fd67bb60128a..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::Pending, + status: enums::AttemptStatus::from(response.outcome.clone()), 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 757760965e76..8ecc3ad792ce 100644 --- a/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/worldpay/transformers.rs @@ -560,7 +560,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, @@ -574,20 +574,38 @@ 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 { 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/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/configs/defaults/payment_connector_required_fields.rs b/crates/router/src/configs/defaults/payment_connector_required_fields.rs index 4e80ccf027ec..d359335bf128 100644 --- a/crates/router/src/configs/defaults/payment_connector_required_fields.rs +++ b/crates/router/src/configs/defaults/payment_connector_required_fields.rs @@ -3132,35 +3132,39 @@ impl Default for 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(), } ), @@ -6324,35 +6328,39 @@ impl Default for 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(), } ), @@ -12736,3 +12744,163 @@ impl Default for settings::RequiredFields { ])) } } + +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/core/refunds.rs b/crates/router/src/core/refunds.rs index c3e49a49bb14..c706d8854af5 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, 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, &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) diff --git a/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js b/cypress-tests/cypress/e2e/PaymentUtils/WorldPay.js index 5b950219fb25..d45458369c59 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, @@ -102,7 +104,8 @@ export const connectorDetails = { currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", - }, Response: { + }, + Response: { status: 200, body: { status: "requires_payment_method", @@ -117,7 +120,6 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", billing: billing, @@ -127,7 +129,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, }, @@ -140,16 +142,15 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", }, 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, }, }, }, @@ -226,23 +227,38 @@ 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: { + status: "requires_capture", + }, + }, + }, + SaveCardUseNo3DSManualCaptureOffSession: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, }, + setup_future_usage: "off_session", + customer_acceptance: offileCustomerAcceptance, }, Response: { - status: 400, + status: 200, body: { - error: { - type: "invalid_request", - message: "Missing required param: payment_method_data", - code: "IR_04" - } + status: "requires_capture", + }, + }, + }, + SaveCardConfirmManualCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, }, }, @@ -255,22 +271,43 @@ 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, 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: offileCustomerAcceptance, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + SaveCardConfirmAutoCaptureOffSession: { + Request: { + setup_future_usage: "off_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, "3DSManualCapture": { Request: { payment_method: "card", @@ -278,7 +315,6 @@ export const connectorDetails = { payment_method_data: { card: successfulThreeDsTestCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, setup_future_usage: "on_session", browser_info, @@ -313,10 +349,6 @@ export const connectorDetails = { }, }, }, - - /** - * Variation cases - */ CaptureCapturedAmount: { Request: { Request: { @@ -334,7 +366,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", }, }, @@ -346,7 +378,6 @@ export const connectorDetails = { payment_method_data: { card: successfulNoThreeDsCardDetailsRequest, }, - currency: "USD", customer_acceptance: null, }, Response: { @@ -355,37 +386,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 +404,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 +440,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 +518,116 @@ export const connectorDetails = { mandate_data: singleUseMandateData, }, Response: { + trigger_skip: true, + 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 + }, + }, + }, + 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", + 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: offileCustomerAcceptance, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + PaymentMethodIdMandateNo3DSManualCapture: { + Request: { + payment_method: "card", + payment_method_data: { + card: successfulNoThreeDsCardDetailsRequest, + }, + currency: "USD", + mandate_data: null, + customer_acceptance: offileCustomerAcceptance, + }, + 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: offileCustomerAcceptance, + }, + 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: offileCustomerAcceptance, + }, + 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, diff --git a/cypress-tests/cypress/support/commands.js b/cypress-tests/cypress/support/commands.js index ee64d3247c53..5a6e1b4783e4 100644 --- a/cypress-tests/cypress/support/commands.js +++ b/cypress-tests/cypress/support/commands.js @@ -1793,13 +1793,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( @@ -1915,8 +1915,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"); @@ -2195,11 +2197,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, @@ -2211,7 +2213,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");