mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 09:38:33 +08:00
fix: refund fix with connector_metadata (#330)
This commit is contained in:
@ -354,6 +354,7 @@ impl From<errors::ApiErrorResponse> 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
|
||||
|
||||
@ -218,6 +218,7 @@ impl<F, T>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -429,6 +429,7 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<AdyenCancelResponse>>
|
||||
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<types::PaymentsCaptureResponseRouterData<AdyenCaptureResponse>>
|
||||
redirect: false,
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
amount_captured,
|
||||
..item.data
|
||||
|
||||
@ -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<String, common_utils::pii::CardNumber>,
|
||||
expiration_date: masking::Secret<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
card_code: Option<masking::Secret<String>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, PartialEq)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct BankAccountDetails {
|
||||
account_number: String,
|
||||
account_number: masking::Secret<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, PartialEq)]
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||||
enum PaymentDetails {
|
||||
#[serde(rename = "creditCard")]
|
||||
CreditCard(CreditCardDetails),
|
||||
@ -63,6 +66,29 @@ enum PaymentDetails {
|
||||
Paypal,
|
||||
}
|
||||
|
||||
impl From<api_models::payments::PaymentMethod> 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<enums::CaptureMethod> for AuthorizationType {
|
||||
impl TryFrom<&types::PaymentsAuthorizeRouterData> for CreateTransactionRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
|
||||
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<String>,
|
||||
pub(super) errors: Option<Vec<ErrorMessage>>,
|
||||
}
|
||||
|
||||
@ -294,6 +304,20 @@ impl<F, T>
|
||||
})
|
||||
});
|
||||
|
||||
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<F, T>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: metadata,
|
||||
}),
|
||||
},
|
||||
..item.data
|
||||
@ -340,32 +365,26 @@ pub struct CreateRefundRequest {
|
||||
impl<F> TryFrom<&types::RefundsRouterData<F>> for CreateRefundRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
|
||||
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<F, Req>
|
||||
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,
|
||||
})
|
||||
}
|
||||
|
||||
@ -212,6 +212,7 @@ impl<F, T>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -220,6 +220,7 @@ impl TryFrom<types::PaymentsResponseRouterData<PaymentsResponse>>
|
||||
redirect: redirection_data.is_some(),
|
||||
redirection_data,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
@ -259,6 +260,7 @@ impl TryFrom<types::PaymentsSyncResponseRouterData<PaymentsResponse>>
|
||||
redirect: redirection_data.is_some(),
|
||||
redirection_data,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
@ -301,6 +303,7 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<PaymentVoidResponse>>
|
||||
redirect: false,
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
status: response.into(),
|
||||
..item.data
|
||||
@ -372,6 +375,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<PaymentCaptureResponse>>
|
||||
redirect: false,
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
status,
|
||||
amount_captured,
|
||||
|
||||
@ -234,6 +234,7 @@ impl TryFrom<types::PaymentsResponseRouterData<CybersourcePaymentsResponse>>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -131,6 +131,7 @@ impl TryFrom<types::PaymentsResponseRouterData<KlarnaPaymentsResponse>>
|
||||
redirect: true,
|
||||
redirection_data: Some(redirection_data),
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -156,6 +156,7 @@ impl<F, T>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -396,6 +396,7 @@ impl<F, T>
|
||||
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<F, T>
|
||||
redirect: redirection_data.is_some(),
|
||||
redirection_data,
|
||||
mandate_reference,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -161,6 +161,7 @@ impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsR
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..data.clone()
|
||||
})
|
||||
@ -249,6 +250,7 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..data.clone()
|
||||
})
|
||||
@ -306,6 +308,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..data.clone()
|
||||
})
|
||||
|
||||
@ -169,6 +169,7 @@ impl TryFrom<types::PaymentsResponseRouterData<WorldpayPaymentsResponse>>
|
||||
redirection_data: None,
|
||||
redirect: false,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
|
||||
@ -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
|
||||
|
||||
@ -178,6 +178,7 @@ async fn payment_response_update_tracker<F: Clone, T>(
|
||||
resource_id,
|
||||
redirection_data,
|
||||
redirect,
|
||||
connector_metadata,
|
||||
..
|
||||
} => {
|
||||
let connector_transaction_id = match resource_id {
|
||||
@ -206,6 +207,7 @@ async fn payment_response_update_tracker<F: Clone, T>(
|
||||
.mandate_id
|
||||
.clone()
|
||||
.map(|mandate| mandate.mandate_id),
|
||||
connector_metadata,
|
||||
};
|
||||
|
||||
let connector_response_update = storage::ConnectorResponseUpdate::ResponseUpdate {
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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<i64>) -> CustomResult<i64, errors::Api
|
||||
None => 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(())
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
},
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -163,6 +163,7 @@ pub enum PaymentsResponseData {
|
||||
redirection_data: Option<services::RedirectForm>,
|
||||
redirect: bool,
|
||||
mandate_reference: Option<String>,
|
||||
connector_metadata: Option<serde_json::Value>,
|
||||
},
|
||||
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<String>,
|
||||
/// Amount to be refunded
|
||||
pub refund_amount: i64,
|
||||
/// Arbitrary metadata required for refund
|
||||
pub connector_metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
|
||||
@ -82,15 +82,9 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
||||
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,
|
||||
|
||||
@ -82,15 +82,9 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
||||
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()),
|
||||
|
||||
@ -79,15 +79,9 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
||||
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()),
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -38,6 +38,7 @@ pub struct PaymentAttempt {
|
||||
pub browser_info: Option<serde_json::Value>,
|
||||
pub error_code: Option<String>,
|
||||
pub payment_token: Option<String>,
|
||||
pub connector_metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
@ -76,6 +77,7 @@ pub struct PaymentAttemptNew {
|
||||
pub browser_info: Option<serde_json::Value>,
|
||||
pub payment_token: Option<String>,
|
||||
pub error_code: Option<String>,
|
||||
pub connector_metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -116,6 +118,7 @@ pub enum PaymentAttemptUpdate {
|
||||
payment_method_id: Option<Option<String>>,
|
||||
redirect: Option<bool>,
|
||||
mandate_id: Option<String>,
|
||||
connector_metadata: Option<serde_json::Value>,
|
||||
},
|
||||
StatusUpdate {
|
||||
status: storage_enums::AttemptStatus,
|
||||
@ -147,6 +150,7 @@ pub struct PaymentAttemptUpdateInternal {
|
||||
browser_info: Option<serde_json::Value>,
|
||||
payment_token: Option<String>,
|
||||
error_code: Option<String>,
|
||||
connector_metadata: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
impl PaymentAttemptUpdate {
|
||||
@ -238,6 +242,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
|
||||
payment_method_id,
|
||||
redirect,
|
||||
mandate_id,
|
||||
connector_metadata,
|
||||
} => Self {
|
||||
status: Some(status),
|
||||
connector,
|
||||
@ -247,6 +252,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
|
||||
modified_at: Some(common_utils::date_time::now()),
|
||||
redirect,
|
||||
mandate_id,
|
||||
connector_metadata,
|
||||
..Default::default()
|
||||
},
|
||||
PaymentAttemptUpdate::ErrorUpdate {
|
||||
|
||||
@ -217,6 +217,7 @@ diesel::table! {
|
||||
browser_info -> Nullable<Jsonb>,
|
||||
error_code -> Nullable<Varchar>,
|
||||
payment_token -> Nullable<Varchar>,
|
||||
connector_metadata -> Nullable<Jsonb>,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE payment_attempt DROP COLUMN connector_metadata;
|
||||
@ -0,0 +1,2 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE payment_attempt ADD COLUMN connector_metadata JSONB DEFAULT NULL;
|
||||
Reference in New Issue
Block a user