mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
test(stripe): add unit tests for stripe connector (#473)
This commit is contained in:
@ -12,6 +12,7 @@ pub(crate) struct ConnectorAuthentication {
|
||||
pub payu: Option<BodyKey>,
|
||||
pub rapyd: Option<BodyKey>,
|
||||
pub shift4: Option<HeaderKey>,
|
||||
pub stripe: Option<HeaderKey>,
|
||||
pub worldpay: Option<HeaderKey>,
|
||||
pub worldline: Option<SignatureKey>,
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ mod globalpay;
|
||||
mod payu;
|
||||
mod rapyd;
|
||||
mod shift4;
|
||||
mod stripe;
|
||||
mod utils;
|
||||
mod worldline;
|
||||
mod worldpay;
|
||||
|
||||
337
crates/router/tests/connectors/stripe.rs
Normal file
337
crates/router/tests/connectors/stripe.rs
Normal file
@ -0,0 +1,337 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use masking::Secret;
|
||||
use router::types::{self, api, storage::enums};
|
||||
|
||||
use crate::{
|
||||
connector_auth,
|
||||
utils::{self, ConnectorActions},
|
||||
};
|
||||
|
||||
struct Stripe;
|
||||
impl ConnectorActions for Stripe {}
|
||||
impl utils::Connector for Stripe {
|
||||
fn get_data(&self) -> types::api::ConnectorData {
|
||||
use router::connector::Stripe;
|
||||
types::api::ConnectorData {
|
||||
connector: Box::new(&Stripe),
|
||||
connector_name: types::Connector::Stripe,
|
||||
get_token: types::api::GetToken::Connector,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_auth_token(&self) -> types::ConnectorAuthType {
|
||||
types::ConnectorAuthType::from(
|
||||
connector_auth::ConnectorAuthentication::new()
|
||||
.stripe
|
||||
.expect("Missing connector authentication configuration"),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_name(&self) -> String {
|
||||
"stripe".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_payment_authorize_data() -> Option<types::PaymentsAuthorizeData> {
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_number: Secret::new("4242424242424242".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
})
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_only_authorize_payment() {
|
||||
let response = Stripe {}
|
||||
.authorize_payment(get_payment_authorize_data(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(response.status, enums::AttemptStatus::Authorized);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_authorize_and_capture_payment() {
|
||||
let response = Stripe {}
|
||||
.make_payment(get_payment_authorize_data(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(response.status, enums::AttemptStatus::Charged);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_capture_already_authorized_payment() {
|
||||
let connector = Stripe {};
|
||||
let response = connector
|
||||
.authorize_and_capture_payment(get_payment_authorize_data(), None, None)
|
||||
.await;
|
||||
assert_eq!(response.unwrap().status, enums::AttemptStatus::Charged);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_partially_capture_already_authorized_payment() {
|
||||
let connector = Stripe {};
|
||||
let response = connector
|
||||
.authorize_and_capture_payment(
|
||||
get_payment_authorize_data(),
|
||||
Some(types::PaymentsCaptureData {
|
||||
amount_to_capture: Some(50),
|
||||
..utils::PaymentCaptureType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(response.unwrap().status, enums::AttemptStatus::Charged);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_sync_payment() {
|
||||
let connector = Stripe {};
|
||||
let authorize_response = connector
|
||||
.authorize_payment(get_payment_authorize_data(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
let txn_id = utils::get_connector_transaction_id(authorize_response);
|
||||
let response = connector
|
||||
.psync_retry_till_status_matches(
|
||||
enums::AttemptStatus::Authorized,
|
||||
Some(types::PaymentsSyncData {
|
||||
connector_transaction_id: router::types::ResponseId::ConnectorTransactionId(
|
||||
txn_id.unwrap(),
|
||||
),
|
||||
encoded_data: None,
|
||||
capture_method: None,
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(response.status, enums::AttemptStatus::Authorized,);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_void_already_authorized_payment() {
|
||||
let connector = Stripe {};
|
||||
let response = connector
|
||||
.authorize_and_void_payment(
|
||||
get_payment_authorize_data(),
|
||||
Some(types::PaymentsCancelData {
|
||||
connector_transaction_id: "".to_string(),
|
||||
cancellation_reason: Some("requested_by_customer".to_string()),
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
assert_eq!(response.unwrap().status, enums::AttemptStatus::Voided);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_payment_for_incorrect_card_number() {
|
||||
let response = Stripe {}
|
||||
.make_payment(
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_number: Secret::new("4024007134364842".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let x = response.response.unwrap_err();
|
||||
assert_eq!(
|
||||
x.message,
|
||||
"Your card was declined. Your request was in test mode, but used a non test (live) card. For a list of valid test cards, visit: https://stripe.com/docs/testing.",
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_payment_for_no_card_number() {
|
||||
let response = Stripe {}
|
||||
.make_payment(
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_number: Secret::new("".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let x = response.response.unwrap_err();
|
||||
assert_eq!(
|
||||
x.message,
|
||||
"You passed an empty string for 'payment_method_data[card][number]'. We assume empty values are an attempt to unset a parameter; however 'payment_method_data[card][number]' cannot be unset. You should remove 'payment_method_data[card][number]' from your request or supply a non-empty value.",
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_payment_for_invalid_exp_month() {
|
||||
let response = Stripe {}
|
||||
.make_payment(
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_exp_month: Secret::new("13".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let x = response.response.unwrap_err();
|
||||
assert_eq!(x.message, "Your card's expiration month is invalid.",);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_payment_for_invalid_exp_year() {
|
||||
let response = Stripe {}
|
||||
.make_payment(
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_exp_year: Secret::new("2022".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let x = response.response.unwrap_err();
|
||||
assert_eq!(x.message, "Your card's expiration year is invalid.",);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_payment_for_invalid_card_cvc() {
|
||||
let response = Stripe {}
|
||||
.make_payment(
|
||||
Some(types::PaymentsAuthorizeData {
|
||||
payment_method_data: types::api::PaymentMethod::Card(api::CCard {
|
||||
card_cvc: Secret::new("12".to_string()),
|
||||
..utils::CCardType::default().0
|
||||
}),
|
||||
..utils::PaymentAuthorizeType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
let x = response.response.unwrap_err();
|
||||
assert_eq!(x.message, "Your card's security code is invalid.",);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_capture_for_invalid_payment() {
|
||||
let connector = Stripe {};
|
||||
let authorize_response = connector
|
||||
.authorize_payment(get_payment_authorize_data(), None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(authorize_response.status, enums::AttemptStatus::Authorized);
|
||||
tokio::time::sleep(Duration::from_secs(5)).await; // to avoid 404 error as stripe takes some time to process the new transaction
|
||||
let response = connector
|
||||
.capture_payment("12345".to_string(), None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
let err = response.response.unwrap_err();
|
||||
assert_eq!(err.message, "No such payment_intent: '12345'".to_string());
|
||||
assert_eq!(err.code, "resource_missing".to_string());
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_refund_succeeded_payment() {
|
||||
let connector = Stripe {};
|
||||
let response = connector
|
||||
.make_payment_and_refund(get_payment_authorize_data(), None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
response.response.unwrap().refund_status,
|
||||
enums::RefundStatus::Success,
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_partially_refund_succeeded_payment() {
|
||||
let connector = Stripe {};
|
||||
let refund_response = connector
|
||||
.make_payment_and_refund(
|
||||
get_payment_authorize_data(),
|
||||
Some(types::RefundsData {
|
||||
refund_amount: 50,
|
||||
..utils::PaymentRefundType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
refund_response.response.unwrap().refund_status,
|
||||
enums::RefundStatus::Success,
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_refund_succeeded_payment_multiple_times() {
|
||||
let connector = Stripe {};
|
||||
connector
|
||||
.make_payment_and_multiple_refund(
|
||||
get_payment_authorize_data(),
|
||||
Some(types::RefundsData {
|
||||
refund_amount: 50,
|
||||
..utils::PaymentRefundType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_fail_refund_for_invalid_amount() {
|
||||
let connector = Stripe {};
|
||||
let response = connector
|
||||
.make_payment_and_refund(
|
||||
get_payment_authorize_data(),
|
||||
Some(types::RefundsData {
|
||||
refund_amount: 150,
|
||||
..utils::PaymentRefundType::default().0
|
||||
}),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
response.response.unwrap_err().message,
|
||||
"Refund amount ($1.50) is greater than charge amount ($1.00)",
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn should_sync_refund() {
|
||||
let connector = Stripe {};
|
||||
let refund_response = connector
|
||||
.make_payment_and_refund(get_payment_authorize_data(), None, None)
|
||||
.await
|
||||
.unwrap();
|
||||
let response = connector
|
||||
.rsync_retry_till_status_matches(
|
||||
enums::RefundStatus::Success,
|
||||
refund_response.response.unwrap().connector_refund_id,
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
response.response.unwrap().refund_status,
|
||||
enums::RefundStatus::Success,
|
||||
);
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
use std::{fmt::Debug, marker::PhantomData, thread::sleep, time::Duration};
|
||||
use std::{fmt::Debug, marker::PhantomData, time::Duration};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use error_stack::Report;
|
||||
@ -18,6 +18,10 @@ pub trait Connector {
|
||||
fn get_connector_meta(&self) -> Option<serde_json::Value> {
|
||||
None
|
||||
}
|
||||
/// interval in seconds to be followed when making the subsequent request whenever needed
|
||||
fn get_request_interval(&self) -> u64 {
|
||||
5
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
@ -36,14 +40,16 @@ pub trait ConnectorActions: Connector {
|
||||
) -> Result<types::PaymentsAuthorizeRouterData, Report<ConnectorError>> {
|
||||
let integration = self.get_data().connector.get_connector_integration();
|
||||
let request = self.generate_data(
|
||||
payment_data.unwrap_or_else(|| types::PaymentsAuthorizeData {
|
||||
types::PaymentsAuthorizeData {
|
||||
confirm: false,
|
||||
capture_method: Some(storage_models::enums::CaptureMethod::Manual),
|
||||
..PaymentAuthorizeType::default().0
|
||||
}),
|
||||
..(payment_data.unwrap_or(PaymentAuthorizeType::default().0))
|
||||
},
|
||||
payment_info,
|
||||
);
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
async fn make_payment(
|
||||
&self,
|
||||
payment_data: Option<types::PaymentsAuthorizeData>,
|
||||
@ -70,25 +76,23 @@ pub trait ConnectorActions: Connector {
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
/// will retry the psync till the given status matches or retry max 3 times in a 10secs interval
|
||||
/// will retry the psync till the given status matches or retry max 3 times
|
||||
async fn psync_retry_till_status_matches(
|
||||
&self,
|
||||
status: enums::AttemptStatus,
|
||||
payment_data: Option<types::PaymentsSyncData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::PaymentsSyncRouterData, Report<ConnectorError>> {
|
||||
let max_try = 3;
|
||||
let mut curr_try = 1;
|
||||
while curr_try <= max_try {
|
||||
let max_tries = 3;
|
||||
for curr_try in 0..max_tries {
|
||||
let sync_res = self
|
||||
.sync_payment(payment_data.clone(), payment_info.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
if (sync_res.status == status) || (curr_try == max_try) {
|
||||
if (sync_res.status == status) || (curr_try == max_tries - 1) {
|
||||
return Ok(sync_res);
|
||||
}
|
||||
sleep(Duration::from_secs(10));
|
||||
curr_try += 1;
|
||||
tokio::time::sleep(Duration::from_secs(self.get_request_interval())).await;
|
||||
}
|
||||
Err(errors::ConnectorError::ProcessingStepFailed(None).into())
|
||||
}
|
||||
@ -101,17 +105,34 @@ pub trait ConnectorActions: Connector {
|
||||
) -> Result<types::PaymentsCaptureRouterData, Report<ConnectorError>> {
|
||||
let integration = self.get_data().connector.get_connector_integration();
|
||||
let request = self.generate_data(
|
||||
payment_data.unwrap_or(types::PaymentsCaptureData {
|
||||
amount_to_capture: Some(100),
|
||||
currency: enums::Currency::USD,
|
||||
types::PaymentsCaptureData {
|
||||
connector_transaction_id: transaction_id,
|
||||
amount: 100,
|
||||
}),
|
||||
..payment_data.unwrap_or(PaymentCaptureType::default().0)
|
||||
},
|
||||
payment_info,
|
||||
);
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
async fn authorize_and_capture_payment(
|
||||
&self,
|
||||
authorize_data: Option<types::PaymentsAuthorizeData>,
|
||||
capture_data: Option<types::PaymentsCaptureData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::PaymentsCaptureRouterData, Report<ConnectorError>> {
|
||||
let authorize_response = self
|
||||
.authorize_payment(authorize_data, payment_info.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(authorize_response.status, enums::AttemptStatus::Authorized);
|
||||
let txn_id = get_connector_transaction_id(authorize_response);
|
||||
let response = self
|
||||
.capture_payment(txn_id.unwrap(), capture_data, payment_info)
|
||||
.await
|
||||
.unwrap();
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
async fn void_payment(
|
||||
&self,
|
||||
transaction_id: String,
|
||||
@ -120,15 +141,35 @@ pub trait ConnectorActions: Connector {
|
||||
) -> Result<types::PaymentsCancelRouterData, Report<ConnectorError>> {
|
||||
let integration = self.get_data().connector.get_connector_integration();
|
||||
let request = self.generate_data(
|
||||
payment_data.unwrap_or(types::PaymentsCancelData {
|
||||
types::PaymentsCancelData {
|
||||
connector_transaction_id: transaction_id,
|
||||
cancellation_reason: Some("Test cancellation".to_string()),
|
||||
}),
|
||||
..payment_data.unwrap_or(PaymentCancelType::default().0)
|
||||
},
|
||||
payment_info,
|
||||
);
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
async fn authorize_and_void_payment(
|
||||
&self,
|
||||
authorize_data: Option<types::PaymentsAuthorizeData>,
|
||||
void_data: Option<types::PaymentsCancelData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::PaymentsCancelRouterData, Report<ConnectorError>> {
|
||||
let authorize_response = self
|
||||
.authorize_payment(authorize_data, payment_info.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(authorize_response.status, enums::AttemptStatus::Authorized);
|
||||
let txn_id = get_connector_transaction_id(authorize_response);
|
||||
tokio::time::sleep(Duration::from_secs(self.get_request_interval())).await; // to avoid 404 error
|
||||
let response = self
|
||||
.void_payment(txn_id.unwrap(), void_data, payment_info)
|
||||
.await
|
||||
.unwrap();
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
async fn refund_payment(
|
||||
&self,
|
||||
transaction_id: String,
|
||||
@ -137,24 +178,70 @@ pub trait ConnectorActions: Connector {
|
||||
) -> Result<types::RefundExecuteRouterData, Report<ConnectorError>> {
|
||||
let integration = self.get_data().connector.get_connector_integration();
|
||||
let request = self.generate_data(
|
||||
payment_data.unwrap_or_else(|| types::RefundsData {
|
||||
amount: 100,
|
||||
currency: enums::Currency::USD,
|
||||
refund_id: uuid::Uuid::new_v4().to_string(),
|
||||
types::RefundsData {
|
||||
connector_transaction_id: transaction_id,
|
||||
refund_amount: 100,
|
||||
connector_metadata: None,
|
||||
connector_refund_id: None,
|
||||
reason: Some("Customer returned product".to_string()),
|
||||
}),
|
||||
..payment_data.unwrap_or(PaymentRefundType::default().0)
|
||||
},
|
||||
payment_info,
|
||||
);
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
async fn make_payment_and_refund(
|
||||
&self,
|
||||
authorize_data: Option<types::PaymentsAuthorizeData>,
|
||||
refund_data: Option<types::RefundsData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::RefundExecuteRouterData, Report<ConnectorError>> {
|
||||
//make a successful payment
|
||||
let response = self
|
||||
.make_payment(authorize_data, payment_info.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
//try refund for previous payment
|
||||
let transaction_id = get_connector_transaction_id(response).unwrap();
|
||||
tokio::time::sleep(Duration::from_secs(self.get_request_interval())).await; // to avoid 404 error
|
||||
Ok(self
|
||||
.refund_payment(transaction_id, refund_data, payment_info)
|
||||
.await
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
async fn make_payment_and_multiple_refund(
|
||||
&self,
|
||||
authorize_data: Option<types::PaymentsAuthorizeData>,
|
||||
refund_data: Option<types::RefundsData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) {
|
||||
//make a successful payment
|
||||
let response = self
|
||||
.make_payment(authorize_data, payment_info.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
//try refund for previous payment
|
||||
let transaction_id = get_connector_transaction_id(response).unwrap();
|
||||
for _x in 0..2 {
|
||||
tokio::time::sleep(Duration::from_secs(self.get_request_interval())).await; // to avoid 404 error
|
||||
let refund_response = self
|
||||
.refund_payment(
|
||||
transaction_id.clone(),
|
||||
refund_data.clone(),
|
||||
payment_info.clone(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
refund_response.response.unwrap().refund_status,
|
||||
enums::RefundStatus::Success,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async fn sync_refund(
|
||||
&self,
|
||||
transaction_id: String,
|
||||
refund_id: String,
|
||||
payment_data: Option<types::RefundsData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::RefundSyncRouterData, Report<ConnectorError>> {
|
||||
@ -164,17 +251,45 @@ pub trait ConnectorActions: Connector {
|
||||
amount: 1000,
|
||||
currency: enums::Currency::USD,
|
||||
refund_id: uuid::Uuid::new_v4().to_string(),
|
||||
connector_transaction_id: transaction_id,
|
||||
connector_transaction_id: "".to_string(),
|
||||
refund_amount: 100,
|
||||
connector_metadata: None,
|
||||
reason: None,
|
||||
connector_refund_id: None,
|
||||
connector_refund_id: Some(refund_id),
|
||||
}),
|
||||
payment_info,
|
||||
);
|
||||
call_connector(request, integration).await
|
||||
}
|
||||
|
||||
/// will retry the rsync till the given status matches or retry max 3 times
|
||||
async fn rsync_retry_till_status_matches(
|
||||
&self,
|
||||
status: enums::RefundStatus,
|
||||
refund_id: String,
|
||||
payment_data: Option<types::RefundsData>,
|
||||
payment_info: Option<PaymentInfo>,
|
||||
) -> Result<types::RefundSyncRouterData, Report<ConnectorError>> {
|
||||
let max_tries = 3;
|
||||
for curr_try in 0..max_tries {
|
||||
let sync_res = self
|
||||
.sync_refund(
|
||||
refund_id.clone(),
|
||||
payment_data.clone(),
|
||||
payment_info.clone(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
if (sync_res.clone().response.unwrap().refund_status == status)
|
||||
|| (curr_try == max_tries - 1)
|
||||
{
|
||||
return Ok(sync_res);
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(self.get_request_interval())).await;
|
||||
}
|
||||
Err(errors::ConnectorError::ProcessingStepFailed(None).into())
|
||||
}
|
||||
|
||||
fn generate_data<Flow, Req: From<Req>, Res>(
|
||||
&self,
|
||||
req: Req,
|
||||
@ -258,6 +373,8 @@ pub trait LocalMock {
|
||||
}
|
||||
|
||||
pub struct PaymentAuthorizeType(pub types::PaymentsAuthorizeData);
|
||||
pub struct PaymentCaptureType(pub types::PaymentsCaptureData);
|
||||
pub struct PaymentCancelType(pub types::PaymentsCancelData);
|
||||
pub struct PaymentSyncType(pub types::PaymentsSyncData);
|
||||
pub struct PaymentRefundType(pub types::RefundsData);
|
||||
pub struct CCardType(pub api::CCard);
|
||||
@ -296,6 +413,26 @@ impl Default for PaymentAuthorizeType {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PaymentCaptureType {
|
||||
fn default() -> Self {
|
||||
Self(types::PaymentsCaptureData {
|
||||
amount_to_capture: Some(100),
|
||||
currency: enums::Currency::USD,
|
||||
connector_transaction_id: "".to_string(),
|
||||
amount: 100,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PaymentCancelType {
|
||||
fn default() -> Self {
|
||||
Self(types::PaymentsCancelData {
|
||||
cancellation_reason: Some("requested_by_customer".to_string()),
|
||||
connector_transaction_id: "".to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BrowserInfoType {
|
||||
fn default() -> Self {
|
||||
let data = types::BrowserInformation {
|
||||
@ -330,13 +467,13 @@ impl Default for PaymentSyncType {
|
||||
impl Default for PaymentRefundType {
|
||||
fn default() -> Self {
|
||||
let data = types::RefundsData {
|
||||
amount: 1000,
|
||||
amount: 100,
|
||||
currency: enums::Currency::USD,
|
||||
refund_id: uuid::Uuid::new_v4().to_string(),
|
||||
connector_transaction_id: String::new(),
|
||||
refund_amount: 100,
|
||||
connector_metadata: None,
|
||||
reason: None,
|
||||
reason: Some("Customer returned product".to_string()),
|
||||
connector_refund_id: None,
|
||||
};
|
||||
Self(data)
|
||||
|
||||
Reference in New Issue
Block a user