diff --git a/crates/router/src/compatibility/stripe/errors.rs b/crates/router/src/compatibility/stripe/errors.rs index fb197d0dd9..f16ced793a 100644 --- a/crates/router/src/compatibility/stripe/errors.rs +++ b/crates/router/src/compatibility/stripe/errors.rs @@ -354,6 +354,7 @@ impl From for StripeErrorCode { } errors::ApiErrorResponse::InvalidCardData { data } => Self::InvalidCardType, // Maybe it is better to de generalize this router error errors::ApiErrorResponse::CardExpired { data } => Self::ExpiredCard, + errors::ApiErrorResponse::RefundNotPossible { connector } => Self::RefundFailed, errors::ApiErrorResponse::RefundFailed { data } => Self::RefundFailed, // Nothing at stripe to map errors::ApiErrorResponse::InternalServerError => Self::InternalServerError, // not a stripe code diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs index 09a6e7b22b..048d7574f0 100644 --- a/crates/router/src/connector/aci/transformers.rs +++ b/crates/router/src/connector/aci/transformers.rs @@ -218,6 +218,7 @@ impl redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 0219159709..d06be6bffa 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -429,6 +429,7 @@ impl TryFrom> redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) @@ -477,6 +478,7 @@ pub fn get_adyen_response( redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }; Ok((status, error, payments_response_data)) } @@ -542,6 +544,7 @@ pub fn get_redirection_response( redirection_data: Some(redirection_data), redirect: true, mandate_reference: None, + connector_metadata: None, }; Ok((status, error, payments_response_data)) } @@ -635,6 +638,7 @@ impl TryFrom> redirect: false, redirection_data: None, mandate_reference: None, + connector_metadata: None, }), amount_captured, ..item.data diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 2571533cef..6edd7a9047 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -1,3 +1,4 @@ +use common_utils::ext_traits::{Encode, ValueExt}; use error_stack::ResultExt; use serde::{Deserialize, Serialize}; @@ -5,6 +6,7 @@ use crate::{ core::errors, pii::PeekInterface, types::{self, api, storage::enums}, + utils::OptionExt, }; #[derive(Debug, Serialize, PartialEq, Eq)] @@ -38,21 +40,22 @@ impl TryFrom<&types::ConnectorAuthType> for MerchantAuthentication { } } -#[derive(Serialize, PartialEq)] +#[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] struct CreditCardDetails { - card_number: String, - expiration_date: String, - card_code: String, + card_number: masking::Secret, + expiration_date: masking::Secret, + #[serde(skip_serializing_if = "Option::is_none")] + card_code: Option>, } -#[derive(Serialize, PartialEq)] +#[derive(Serialize, Deserialize, PartialEq, Debug)] #[serde(rename_all = "camelCase")] struct BankAccountDetails { - account_number: String, + account_number: masking::Secret, } -#[derive(Serialize, PartialEq)] +#[derive(Serialize, Deserialize, PartialEq, Debug)] enum PaymentDetails { #[serde(rename = "creditCard")] CreditCard(CreditCardDetails), @@ -63,6 +66,29 @@ enum PaymentDetails { Paypal, } +impl From for PaymentDetails { + fn from(value: api_models::payments::PaymentMethod) -> Self { + match value { + api::PaymentMethod::Card(ref ccard) => { + let expiry_month = ccard.card_exp_month.peek().clone(); + let expiry_year = ccard.card_exp_year.peek().clone(); + + Self::CreditCard(CreditCardDetails { + card_number: ccard.card_number.clone(), + expiration_date: format!("{expiry_year}-{expiry_month}").into(), + card_code: Some(ccard.card_cvc.clone()), + }) + } + api::PaymentMethod::BankTransfer => Self::BankAccount(BankAccountDetails { + account_number: "XXXXX".to_string().into(), + }), + api::PaymentMethod::PayLater(_) => Self::Klarna, + api::PaymentMethod::Wallet(_) => Self::Wallet, + api::PaymentMethod::Paypal => Self::Paypal, + } + } +} + #[derive(Serialize, PartialEq)] #[serde(rename_all = "camelCase")] struct TransactionRequest { @@ -132,24 +158,7 @@ impl From for AuthorizationType { impl TryFrom<&types::PaymentsAuthorizeRouterData> for CreateTransactionRequest { type Error = error_stack::Report; fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result { - let payment_details = match item.request.payment_method_data { - api::PaymentMethod::Card(ref ccard) => { - let expiry_month = ccard.card_exp_month.peek().clone(); - let expiry_year = ccard.card_exp_year.peek().clone(); - - PaymentDetails::CreditCard(CreditCardDetails { - card_number: ccard.card_number.peek().clone(), - expiration_date: format!("{expiry_year}-{expiry_month}"), - card_code: ccard.card_cvc.peek().clone(), - }) - } - api::PaymentMethod::BankTransfer => PaymentDetails::BankAccount(BankAccountDetails { - account_number: "XXXXX".to_string(), - }), - api::PaymentMethod::PayLater(_) => PaymentDetails::Klarna, - api::PaymentMethod::Wallet(_) => PaymentDetails::Wallet, - api::PaymentMethod::Paypal => PaymentDetails::Paypal, - }; + let payment_details = item.request.payment_method_data.clone().into(); let authorization_indicator_type = item.request.capture_method.map(|c| AuthorizationIndicator { authorization_indicator: c.into(), @@ -252,6 +261,7 @@ pub struct TransactionResponse { auth_code: String, #[serde(rename = "transId")] transaction_id: String, + pub(super) account_number: Option, pub(super) errors: Option>, } @@ -294,6 +304,20 @@ impl }) }); + let metadata = item + .response + .transaction_response + .account_number + .map(|acc_no| { + Encode::<'_, PaymentDetails>::encode_to_value(&construct_refund_payment_details( + acc_no, + )) + }) + .transpose() + .change_context(errors::ConnectorError::MissingRequiredField { + field_name: "connector_metadata".to_string(), + })?; + Ok(Self { status, response: match error { @@ -305,6 +329,7 @@ impl redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: metadata, }), }, ..item.data @@ -340,32 +365,26 @@ pub struct CreateRefundRequest { impl TryFrom<&types::RefundsRouterData> for CreateRefundRequest { type Error = error_stack::Report; fn try_from(item: &types::RefundsRouterData) -> Result { - let (payment_details, merchant_authentication, transaction_request); - payment_details = match item.request.payment_method_data { - api::PaymentMethod::Card(ref ccard) => { - let expiry_month = ccard.card_exp_month.peek().clone(); - let expiry_year = ccard.card_exp_year.peek().clone(); + let payment_details = item + .request + .connector_metadata + .as_ref() + .get_required_value("connector_metadata") + .change_context(errors::ConnectorError::MissingRequiredField { + field_name: "connector_metadata".to_string(), + })? + .clone(); - PaymentDetails::CreditCard(CreditCardDetails { - card_number: ccard.card_number.peek().clone(), - expiration_date: format!("{expiry_year}-{expiry_month}"), - card_code: ccard.card_cvc.peek().clone(), - }) - } - api::PaymentMethod::BankTransfer => PaymentDetails::BankAccount(BankAccountDetails { - account_number: "XXXXX".to_string(), - }), - api::PaymentMethod::PayLater(_) => PaymentDetails::Klarna, - api::PaymentMethod::Wallet(_) => PaymentDetails::Wallet, - api::PaymentMethod::Paypal => PaymentDetails::Paypal, - }; + let merchant_authentication = MerchantAuthentication::try_from(&item.connector_auth_type)?; - merchant_authentication = MerchantAuthentication::try_from(&item.connector_auth_type)?; - - transaction_request = RefundTransactionRequest { + let transaction_request = RefundTransactionRequest { transaction_type: TransactionType::Refund, amount: item.request.refund_amount, - payment: payment_details, + payment: payment_details + .parse_value("PaymentDetails") + .change_context(errors::ConnectorError::MissingRequiredField { + field_name: "payment_details".to_string(), + })?, currency_code: item.request.currency.to_string(), reference_transaction_id: item.request.connector_transaction_id.clone(), }; @@ -590,6 +609,7 @@ impl redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), status: payment_status, ..item.data @@ -610,3 +630,11 @@ pub struct ErrorDetails { pub struct AuthorizedotnetErrorResponse { pub error: ErrorDetails, } + +fn construct_refund_payment_details(masked_number: String) -> PaymentDetails { + PaymentDetails::CreditCard(CreditCardDetails { + card_number: masked_number.into(), + expiration_date: "XXXX".to_string().into(), + card_code: None, + }) +} diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs index 28d3ed8a18..ec838710d0 100644 --- a/crates/router/src/connector/braintree/transformers.rs +++ b/crates/router/src/connector/braintree/transformers.rs @@ -212,6 +212,7 @@ impl redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index 2539d3564e..4a3727dc38 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -220,6 +220,7 @@ impl TryFrom> redirect: redirection_data.is_some(), redirection_data, mandate_reference: None, + connector_metadata: None, }), ..item.data }) @@ -259,6 +260,7 @@ impl TryFrom> redirect: redirection_data.is_some(), redirection_data, mandate_reference: None, + connector_metadata: None, }), ..item.data }) @@ -301,6 +303,7 @@ impl TryFrom> redirect: false, redirection_data: None, mandate_reference: None, + connector_metadata: None, }), status: response.into(), ..item.data @@ -372,6 +375,7 @@ impl TryFrom> redirect: false, redirection_data: None, mandate_reference: None, + connector_metadata: None, }), status, amount_captured, diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index 7e1565e521..6881bda460 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -234,6 +234,7 @@ impl TryFrom> redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/klarna/transformers.rs b/crates/router/src/connector/klarna/transformers.rs index 64a777c0ce..e577e44674 100644 --- a/crates/router/src/connector/klarna/transformers.rs +++ b/crates/router/src/connector/klarna/transformers.rs @@ -131,6 +131,7 @@ impl TryFrom> redirect: true, redirection_data: Some(redirection_data), mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs index e7d3439d38..896ba7842d 100644 --- a/crates/router/src/connector/shift4/transformers.rs +++ b/crates/router/src/connector/shift4/transformers.rs @@ -156,6 +156,7 @@ impl redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index d7658e05d2..87f103fc9e 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -396,6 +396,7 @@ impl redirect: redirection_data.is_some(), redirection_data, mandate_reference, + connector_metadata: None, }), amount_captured: Some(item.response.amount_received), ..item.data @@ -445,6 +446,7 @@ impl redirect: redirection_data.is_some(), redirection_data, mandate_reference, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/connector/worldpay.rs b/crates/router/src/connector/worldpay.rs index e2d9741e9d..f6668a7526 100644 --- a/crates/router/src/connector/worldpay.rs +++ b/crates/router/src/connector/worldpay.rs @@ -161,6 +161,7 @@ impl ConnectorIntegration> redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }), ..item.data }) diff --git a/crates/router/src/core/errors/api_error_response.rs b/crates/router/src/core/errors/api_error_response.rs index 7f463d4d49..e02ee36a3e 100644 --- a/crates/router/src/core/errors/api_error_response.rs +++ b/crates/router/src/core/errors/api_error_response.rs @@ -107,6 +107,8 @@ pub enum ApiErrorResponse { MandateNotFound, #[error(error_type = ErrorType::ValidationError, code = "RE_03", message = "Return URL is not configured and not passed in payments request.")] ReturnUrlUnavailable, + #[error(error_type = ErrorType::ValidationError, code = "RE_03", message = "Refunds not possible through hyperswitch. Please raise Refunds through {connector} dashboard")] + RefundNotPossible { connector: String }, #[error(error_type = ErrorType::DuplicateRequest, code = "RE_04", message = "The merchant account with the specified details already exists in our records.")] DuplicateMerchantAccount, #[error(error_type = ErrorType::DuplicateRequest, code = "RE_04", message = "The merchant connector account with the specified details already exists in our records.")] @@ -163,6 +165,7 @@ impl actix_web::ResponseError for ApiErrorResponse { | Self::InvalidCardData { .. } | Self::CardExpired { .. } | Self::RefundFailed { .. } + | Self::RefundNotPossible { .. } | Self::VerificationFailed { .. } | Self::PaymentUnexpectedState { .. } | Self::MandateValidationFailed { .. } => StatusCode::BAD_REQUEST, // 400 diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 12eb7f93c7..1383a19542 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -178,6 +178,7 @@ async fn payment_response_update_tracker( resource_id, redirection_data, redirect, + connector_metadata, .. } => { let connector_transaction_id = match resource_id { @@ -206,6 +207,7 @@ async fn payment_response_update_tracker( .mandate_id .clone() .map(|mandate| mandate.mandate_id), + connector_metadata, }; let connector_response_update = storage::ConnectorResponseUpdate::ResponseUpdate { diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index f24fa8da54..6e81c9c602 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -66,6 +66,7 @@ where redirection_data: None, redirect: false, mandate_reference: None, + connector_metadata: None, }); let router_return_url = Some(helpers::create_redirect_url( diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs index d021f49bd0..102a82ab6b 100644 --- a/crates/router/src/core/refunds.rs +++ b/crates/router/src/core/refunds.rs @@ -113,12 +113,13 @@ pub async fn trigger_refund_to_gateway( .attach_printable("Transaction in invalid") })?; + validator::validate_for_valid_refunds(payment_attempt)?; + let router_data = core_utils::construct_refund_router_data( state, &connector_id, merchant_account, (payment_attempt.amount, currency), - None, payment_intent, payment_attempt, refund, @@ -261,7 +262,6 @@ pub async fn sync_refund_with_gateway( &connector_id, merchant_account, (payment_attempt.amount, currency), - None, payment_intent, payment_attempt, refund, diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs index 3b80cff0e3..10a1219ae6 100644 --- a/crates/router/src/core/refunds/validator.rs +++ b/crates/router/src/core/refunds/validator.rs @@ -1,4 +1,5 @@ -use error_stack::report; +use common_utils::ext_traits::StringExt; +use error_stack::{report, ResultExt}; use router_env::{instrument, tracing}; use time::PrimitiveDateTime; @@ -7,7 +8,7 @@ use crate::{ db::StorageInterface, logger, types::storage::{self, enums}, - utils, + utils::{self, OptionExt}, }; #[derive(Debug, thiserror::Error)] @@ -135,3 +136,35 @@ pub fn validate_refund_list(limit: Option) -> CustomResult Ok(10), } } + +pub fn validate_for_valid_refunds( + payment_attempt: &storage_models::payment_attempt::PaymentAttempt, +) -> RouterResult<()> { + let connector: api_models::enums::Connector = payment_attempt + .connector + .clone() + .get_required_value("connector")? + .parse_enum("connector") + .change_context(errors::ApiErrorResponse::IncorrectConnectorNameGiven)?; + let payment_method = payment_attempt + .payment_method + .get_required_value("payment_method")?; + utils::when( + matches!( + (connector, payment_method), + ( + api_models::enums::Connector::Braintree, + storage_models::enums::PaymentMethodType::Paypal + ) | ( + api_models::enums::Connector::Klarna, + storage_models::enums::PaymentMethodType::Klarna + ) + ), + || { + Err(errors::ApiErrorResponse::RefundNotPossible { + connector: connector.to_string(), + }) + }, + )?; + Ok(()) +} diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs index 86fa3fbfc7..ce050694b8 100644 --- a/crates/router/src/core/utils.rs +++ b/crates/router/src/core/utils.rs @@ -3,13 +3,13 @@ use std::marker::PhantomData; use error_stack::ResultExt; use router_env::{instrument, tracing}; -use super::payments::{helpers, PaymentAddress}; +use super::payments::PaymentAddress; use crate::{ consts, core::errors::{self, RouterResult}, routes::AppState, types::{ - self, api, + self, storage::{self, enums}, }, utils::{generate_id, OptionExt, ValueExt}, @@ -22,7 +22,6 @@ pub async fn construct_refund_router_data<'a, F>( connector_id: &str, merchant_account: &storage::MerchantAccount, money: (i64, enums::Currency), - payment_method_data: Option<&'a api::PaymentMethod>, payment_intent: &'a storage::PaymentIntent, payment_attempt: &storage::PaymentAttempt, refund: &'a storage::Refund, @@ -48,17 +47,6 @@ pub async fn construct_refund_router_data<'a, F>( let payment_method_type = payment_attempt .payment_method .get_required_value("payment_method_type")?; - let payment_method_data = match payment_method_data.cloned() { - Some(v) => v, - None => { - let (pm, _) = helpers::Vault::get_payment_method_data_from_locker( - state, - &payment_attempt.attempt_id, - ) - .await?; - pm.get_required_value("payment_method_data")? - } - }; let router_data = types::RouterData { flow: PhantomData, @@ -80,11 +68,11 @@ pub async fn construct_refund_router_data<'a, F>( amount_captured: payment_intent.amount_captured, request: types::RefundsData { refund_id: refund.refund_id.clone(), - payment_method_data, connector_transaction_id: refund.connector_transaction_id.clone(), refund_amount: refund.refund_amount, currency, amount, + connector_metadata: payment_attempt.connector_metadata.clone(), reason: refund.refund_reason.clone(), }, diff --git a/crates/router/src/db/payment_attempt.rs b/crates/router/src/db/payment_attempt.rs index 752af6acb6..cac74b8818 100644 --- a/crates/router/src/db/payment_attempt.rs +++ b/crates/router/src/db/payment_attempt.rs @@ -243,6 +243,7 @@ impl PaymentAttemptInterface for MockDb { browser_info: None, payment_token: None, error_code: payment_attempt.error_code, + connector_metadata: None, }; payment_attempts.push(payment_attempt.clone()); Ok(payment_attempt) @@ -381,6 +382,7 @@ mod storage { browser_info: payment_attempt.browser_info.clone(), payment_token: payment_attempt.payment_token.clone(), error_code: payment_attempt.error_code.clone(), + connector_metadata: payment_attempt.connector_metadata.clone(), }; let field = format!("pa_{}", created_attempt.attempt_id); diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index 5cb34ad48f..d4c1cc0e3b 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -163,6 +163,7 @@ pub enum PaymentsResponseData { redirection_data: Option, redirect: bool, mandate_reference: Option, + connector_metadata: Option, }, SessionResponse { session_token: api::SessionToken, @@ -195,7 +196,6 @@ impl ResponseId { #[derive(Debug, Clone)] pub struct RefundsData { pub refund_id: String, - pub payment_method_data: payments::PaymentMethod, pub connector_transaction_id: String, pub currency: storage_enums::Currency, /// Amount for the payment against which this refund is issued @@ -203,6 +203,8 @@ pub struct RefundsData { pub reason: Option, /// Amount to be refunded pub refund_amount: i64, + /// Arbitrary metadata required for refund + pub connector_metadata: Option, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs index 6922ffc364..749dfef4a9 100644 --- a/crates/router/tests/connectors/aci.rs +++ b/crates/router/tests/connectors/aci.rs @@ -82,15 +82,9 @@ fn construct_refund_router_data() -> types::RefundsRouterData { currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(types::api::CCard { - card_number: Secret::new("4200000000000000".to_string()), - card_exp_month: Secret::new("10".to_string()), - card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Secret::new("John Doe".to_string()), - card_cvc: Secret::new("999".to_string()), - }), connector_transaction_id: String::new(), refund_amount: 100, + connector_metadata: None, reason: None, }, payment_method_id: None, diff --git a/crates/router/tests/connectors/authorizedotnet.rs b/crates/router/tests/connectors/authorizedotnet.rs index 28dec76dfe..ca9102ec47 100644 --- a/crates/router/tests/connectors/authorizedotnet.rs +++ b/crates/router/tests/connectors/authorizedotnet.rs @@ -82,15 +82,9 @@ fn construct_refund_router_data() -> types::RefundsRouterData { amount: 100, currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(types::api::CCard { - card_number: Secret::new("5424000000000015".to_string()), - card_exp_month: Secret::new("10".to_string()), - card_exp_year: Secret::new("2025".to_string()), - card_holder_name: Secret::new("John Doe".to_string()), - card_cvc: Secret::new("999".to_string()), - }), connector_transaction_id: String::new(), refund_amount: 1, + connector_metadata: None, reason: None, }, response: Err(types::ErrorResponse::default()), diff --git a/crates/router/tests/connectors/checkout.rs b/crates/router/tests/connectors/checkout.rs index 34cd565a47..3e2cb72a8a 100644 --- a/crates/router/tests/connectors/checkout.rs +++ b/crates/router/tests/connectors/checkout.rs @@ -79,15 +79,9 @@ fn construct_refund_router_data() -> types::RefundsRouterData { amount: 100, currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(api::CCard { - card_number: "4242424242424242".to_string().into(), - card_exp_month: "10".to_string().into(), - card_exp_year: "35".to_string().into(), - card_holder_name: "John Doe".to_string().into(), - card_cvc: "123".to_string().into(), - }), connector_transaction_id: String::new(), refund_amount: 10, + connector_metadata: None, reason: None, }, response: Err(types::ErrorResponse::default()), diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index b4266f7b43..11c9d11ec9 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -114,9 +114,9 @@ pub trait ConnectorActions: Connector { amount: 100, currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0), connector_transaction_id: transaction_id, refund_amount: 100, + connector_metadata: None, reason: None, }), ); @@ -137,9 +137,9 @@ pub trait ConnectorActions: Connector { amount: 100, currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0), connector_transaction_id: transaction_id, refund_amount: 100, + connector_metadata: None, reason: None, }), ); @@ -248,9 +248,9 @@ impl Default for PaymentRefundType { amount: 1000, currency: enums::Currency::USD, refund_id: uuid::Uuid::new_v4().to_string(), - payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0), connector_transaction_id: String::new(), refund_amount: 100, + connector_metadata: None, reason: None, }; Self(data) diff --git a/crates/storage_models/src/payment_attempt.rs b/crates/storage_models/src/payment_attempt.rs index 527fbde30c..abb4053f5d 100644 --- a/crates/storage_models/src/payment_attempt.rs +++ b/crates/storage_models/src/payment_attempt.rs @@ -38,6 +38,7 @@ pub struct PaymentAttempt { pub browser_info: Option, pub error_code: Option, pub payment_token: Option, + pub connector_metadata: Option, } #[derive( @@ -76,6 +77,7 @@ pub struct PaymentAttemptNew { pub browser_info: Option, pub payment_token: Option, pub error_code: Option, + pub connector_metadata: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -116,6 +118,7 @@ pub enum PaymentAttemptUpdate { payment_method_id: Option>, redirect: Option, mandate_id: Option, + connector_metadata: Option, }, StatusUpdate { status: storage_enums::AttemptStatus, @@ -147,6 +150,7 @@ pub struct PaymentAttemptUpdateInternal { browser_info: Option, payment_token: Option, error_code: Option, + connector_metadata: Option, } impl PaymentAttemptUpdate { @@ -238,6 +242,7 @@ impl From for PaymentAttemptUpdateInternal { payment_method_id, redirect, mandate_id, + connector_metadata, } => Self { status: Some(status), connector, @@ -247,6 +252,7 @@ impl From for PaymentAttemptUpdateInternal { modified_at: Some(common_utils::date_time::now()), redirect, mandate_id, + connector_metadata, ..Default::default() }, PaymentAttemptUpdate::ErrorUpdate { diff --git a/crates/storage_models/src/schema.rs b/crates/storage_models/src/schema.rs index d70ad30733..22894bd0de 100644 --- a/crates/storage_models/src/schema.rs +++ b/crates/storage_models/src/schema.rs @@ -217,6 +217,7 @@ diesel::table! { browser_info -> Nullable, error_code -> Nullable, payment_token -> Nullable, + connector_metadata -> Nullable, } } diff --git a/migrations/2023-01-10-035412_connector-metadata-payment-attempt/down.sql b/migrations/2023-01-10-035412_connector-metadata-payment-attempt/down.sql new file mode 100644 index 0000000000..88e92850fc --- /dev/null +++ b/migrations/2023-01-10-035412_connector-metadata-payment-attempt/down.sql @@ -0,0 +1,2 @@ +-- This file should undo anything in `up.sql` +ALTER TABLE payment_attempt DROP COLUMN connector_metadata; \ No newline at end of file diff --git a/migrations/2023-01-10-035412_connector-metadata-payment-attempt/up.sql b/migrations/2023-01-10-035412_connector-metadata-payment-attempt/up.sql new file mode 100644 index 0000000000..2894e39aae --- /dev/null +++ b/migrations/2023-01-10-035412_connector-metadata-payment-attempt/up.sql @@ -0,0 +1,2 @@ +-- Your SQL goes here +ALTER TABLE payment_attempt ADD COLUMN connector_metadata JSONB DEFAULT NULL; \ No newline at end of file