Skip to content

Commit

Permalink
Merge branch 'fix-get-card-token-data' of github.com:juspay/hyperswit…
Browse files Browse the repository at this point in the history
…ch into fix-get-card-token-data
  • Loading branch information
Chethan-rao committed Nov 28, 2023
2 parents 8b3640f + 455f79d commit eabdeb7
Show file tree
Hide file tree
Showing 26 changed files with 660 additions and 120 deletions.
155 changes: 54 additions & 101 deletions crates/router/src/connector/adyen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ use crate::{
configs::settings,
connector::utils as connector_utils,
consts,
core::{
self,
errors::{self, CustomResult},
},
headers, logger, routes,
core::errors::{self, CustomResult},
headers, logger,
services::{
self,
request::{self, Mask},
Expand Down Expand Up @@ -560,57 +557,13 @@ impl
}
}

#[async_trait::async_trait]
impl
services::ConnectorIntegration<
api::Authorize,
types::PaymentsAuthorizeData,
types::PaymentsResponseData,
> for Adyen
{
async fn execute_pretasks(
&self,
router_data: &mut types::PaymentsAuthorizeRouterData,
app_state: &routes::AppState,
) -> CustomResult<(), errors::ConnectorError> {
match &router_data.request.payment_method_data {
api_models::payments::PaymentMethodData::GiftCard(gift_card_data) => {
match gift_card_data.as_ref() {
api_models::payments::GiftCardData::Givex(_) => {
let integ: Box<
&(dyn services::ConnectorIntegration<
api::Balance,
types::PaymentsAuthorizeData,
types::PaymentsResponseData,
> + Send
+ Sync
+ 'static),
> = Box::new(&Self);

let authorize_data = &types::PaymentsBalanceRouterData::from((
&router_data.to_owned(),
router_data.request.clone(),
));

let resp = services::execute_connector_processing_step(
app_state,
integ,
authorize_data,
core::payments::CallConnectorAction::Trigger,
None,
)
.await?;
router_data.payment_method_balance = resp.payment_method_balance;

Ok(())
}
_ => Ok(()),
}
}
_ => Ok(()),
}
}

fn get_headers(
&self,
req: &types::PaymentsAuthorizeRouterData,
Expand Down Expand Up @@ -667,7 +620,6 @@ impl
req: &types::PaymentsAuthorizeRouterData,
connectors: &settings::Connectors,
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
check_for_payment_method_balance(req)?;
Ok(Some(
services::RequestBuilder::new()
.method(services::Method::Post)
Expand Down Expand Up @@ -725,28 +677,23 @@ impl
}
}

impl api::PaymentsPreProcessing for Adyen {}

impl
services::ConnectorIntegration<
api::Balance,
types::PaymentsAuthorizeData,
api::PreProcessing,
types::PaymentsPreProcessingData,
types::PaymentsResponseData,
> for Adyen
{
fn get_headers(
&self,
req: &types::PaymentsBalanceRouterData,
req: &types::PaymentsPreProcessingRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError>
where
Self: services::ConnectorIntegration<
api::Balance,
types::PaymentsAuthorizeData,
types::PaymentsResponseData,
>,
{
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
let mut header = vec![(
headers::CONTENT_TYPE.to_string(),
types::PaymentsBalanceType::get_content_type(self)
types::PaymentsPreProcessingType::get_content_type(self)
.to_string()
.into(),
)];
Expand All @@ -757,7 +704,7 @@ impl

fn get_url(
&self,
_req: &types::PaymentsBalanceRouterData,
_req: &types::PaymentsPreProcessingRouterData,
connectors: &settings::Connectors,
) -> CustomResult<String, errors::ConnectorError> {
Ok(format!(
Expand All @@ -768,7 +715,7 @@ impl

fn get_request_body(
&self,
req: &types::PaymentsBalanceRouterData,
req: &types::PaymentsPreProcessingRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> {
let connector_req = adyen::AdyenBalanceRequest::try_from(req)?;
Expand All @@ -783,18 +730,20 @@ impl

fn build_request(
&self,
req: &types::PaymentsBalanceRouterData,
req: &types::PaymentsPreProcessingRouterData,
connectors: &settings::Connectors,
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
Ok(Some(
services::RequestBuilder::new()
.method(services::Method::Post)
.url(&types::PaymentsBalanceType::get_url(self, req, connectors)?)
.url(&types::PaymentsPreProcessingType::get_url(
self, req, connectors,
)?)
.attach_default_headers()
.headers(types::PaymentsBalanceType::get_headers(
.headers(types::PaymentsPreProcessingType::get_headers(
self, req, connectors,
)?)
.body(types::PaymentsBalanceType::get_request_body(
.body(types::PaymentsPreProcessingType::get_request_body(
self, req, connectors,
)?)
.build(),
Expand All @@ -803,19 +752,47 @@ impl

fn handle_response(
&self,
data: &types::PaymentsBalanceRouterData,
data: &types::PaymentsPreProcessingRouterData,
res: types::Response,
) -> CustomResult<types::PaymentsBalanceRouterData, errors::ConnectorError> {
) -> CustomResult<types::PaymentsPreProcessingRouterData, errors::ConnectorError> {
let response: adyen::AdyenBalanceResponse = res
.response
.parse_struct("AdyenBalanceResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
})
.change_context(errors::ConnectorError::ResponseHandlingFailed)

let currency = match data.request.currency {
Some(currency) => currency,
None => Err(errors::ConnectorError::MissingRequiredField {
field_name: "currency",
})?,
};
let amount = match data.request.amount {
Some(amount) => amount,
None => Err(errors::ConnectorError::MissingRequiredField {
field_name: "amount",
})?,
};

if response.balance.currency != currency || response.balance.value < amount {
Ok(types::RouterData {
response: Err(types::ErrorResponse {
code: consts::NO_ERROR_CODE.to_string(),
message: consts::NO_ERROR_MESSAGE.to_string(),
reason: Some(consts::LOW_BALANCE_ERROR_MESSAGE.to_string()),
status_code: res.status_code,
attempt_status: Some(enums::AttemptStatus::Failure),
connector_transaction_id: None,
}),
..data.clone()
})
} else {
types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
})
.change_context(errors::ConnectorError::ResponseHandlingFailed)
}
}

fn get_error_response(
Expand Down Expand Up @@ -1634,7 +1611,7 @@ impl api::IncomingWebhook for Adyen {
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
Ok(api::disputes::DisputePayload {
amount: notif.amount.value.to_string(),
currency: notif.amount.currency,
currency: notif.amount.currency.to_string(),
dispute_stage: api_models::enums::DisputeStage::from(notif.event_code.clone()),
connector_dispute_id: notif.psp_reference,
connector_reason: notif.reason,
Expand All @@ -1646,27 +1623,3 @@ impl api::IncomingWebhook for Adyen {
})
}
}

pub fn check_for_payment_method_balance(
req: &types::PaymentsAuthorizeRouterData,
) -> CustomResult<(), errors::ConnectorError> {
match &req.request.payment_method_data {
api_models::payments::PaymentMethodData::GiftCard(gift_card) => match gift_card.as_ref() {
api_models::payments::GiftCardData::Givex(_) => {
let payment_method_balance = req
.payment_method_balance
.as_ref()
.ok_or(errors::ConnectorError::RequestEncodingFailed)?;
if payment_method_balance.currency != req.request.currency.to_string()
|| payment_method_balance.amount < req.request.amount
{
Err(errors::ConnectorError::InSufficientBalanceInPaymentMethod.into())
} else {
Ok(())
}
}
_ => Ok(()),
},
_ => Ok(()),
}
}
46 changes: 29 additions & 17 deletions crates/router/src/connector/adyen/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ pub struct AdyenBalanceRequest<'a> {
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdyenBalanceResponse {
psp_reference: String,
balance: Amount,
pub psp_reference: String,
pub balance: Amount,
}

/// This implementation will be used only in Authorize, Automatic capture flow.
Expand Down Expand Up @@ -397,8 +397,8 @@ pub enum ActionType {

#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct Amount {
currency: String,
value: i64,
pub currency: storage_enums::Currency,
pub value: i64,
}

#[derive(Debug, Clone, Serialize)]
Expand Down Expand Up @@ -1392,11 +1392,11 @@ impl<'a> TryFrom<&AdyenRouterData<&types::PaymentsAuthorizeRouterData>>
}
}

impl<'a> TryFrom<&types::PaymentsBalanceRouterData> for AdyenBalanceRequest<'a> {
impl<'a> TryFrom<&types::PaymentsPreProcessingRouterData> for AdyenBalanceRequest<'a> {
type Error = Error;
fn try_from(item: &types::PaymentsBalanceRouterData) -> Result<Self, Self::Error> {
fn try_from(item: &types::PaymentsPreProcessingRouterData) -> Result<Self, Self::Error> {
let payment_method = match &item.request.payment_method_data {
payments::PaymentMethodData::GiftCard(gift_card_data) => {
Some(payments::PaymentMethodData::GiftCard(gift_card_data)) => {
match gift_card_data.as_ref() {
payments::GiftCardData::Givex(gift_card_data) => {
let balance_pm = BalancePmData {
Expand Down Expand Up @@ -1510,7 +1510,7 @@ fn get_channel_type(pm_type: &Option<storage_enums::PaymentMethodType>) -> Optio

fn get_amount_data(item: &AdyenRouterData<&types::PaymentsAuthorizeRouterData>) -> Amount {
Amount {
currency: item.router_data.request.currency.to_string(),
currency: item.router_data.request.currency,
value: item.amount.to_owned(),
}
}
Expand Down Expand Up @@ -2857,12 +2857,24 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<AdyenCancelResponse>>
}
}

impl TryFrom<types::PaymentsBalanceResponseRouterData<AdyenBalanceResponse>>
for types::PaymentsBalanceRouterData
impl<F>
TryFrom<
types::ResponseRouterData<
F,
AdyenBalanceResponse,
types::PaymentsPreProcessingData,
types::PaymentsResponseData,
>,
> for types::RouterData<F, types::PaymentsPreProcessingData, types::PaymentsResponseData>
{
type Error = Error;
fn try_from(
item: types::PaymentsBalanceResponseRouterData<AdyenBalanceResponse>,
item: types::ResponseRouterData<
F,
AdyenBalanceResponse,
types::PaymentsPreProcessingData,
types::PaymentsResponseData,
>,
) -> Result<Self, Self::Error> {
Ok(Self {
response: Ok(types::PaymentsResponseData::TransactionResponse {
Expand Down Expand Up @@ -3457,7 +3469,7 @@ impl TryFrom<&AdyenRouterData<&types::PaymentsCaptureRouterData>> for AdyenCaptu
merchant_account: auth_type.merchant_account,
reference,
amount: Amount {
currency: item.router_data.request.currency.to_string(),
currency: item.router_data.request.currency,
value: item.amount.to_owned(),
},
})
Expand Down Expand Up @@ -3547,7 +3559,7 @@ impl<F> TryFrom<&AdyenRouterData<&types::RefundsRouterData<F>>> for AdyenRefundR
Ok(Self {
merchant_account: auth_type.merchant_account,
amount: Amount {
currency: item.router_data.request.currency.to_string(),
currency: item.router_data.request.currency,
value: item.router_data.request.refund_amount,
},
merchant_refund_reason: item.router_data.request.reason.clone(),
Expand Down Expand Up @@ -3629,7 +3641,7 @@ pub struct AdyenAdditionalDataWH {
#[derive(Debug, Deserialize)]
pub struct AdyenAmountWH {
pub value: i64,
pub currency: String,
pub currency: storage_enums::Currency,
}

#[derive(Clone, Debug, Deserialize, Serialize, strum::Display, PartialEq)]
Expand Down Expand Up @@ -3955,7 +3967,7 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutE
)?;
Ok(Self {
amount: Amount {
currency: item.router_data.request.destination_currency.to_string(),
currency: item.router_data.request.destination_currency,
value: item.amount.to_owned(),
},
merchant_account: auth_type.merchant_account,
Expand Down Expand Up @@ -4030,7 +4042,7 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutC
Ok(Self {
amount: Amount {
value: item.amount.to_owned(),
currency: item.router_data.request.destination_currency.to_string(),
currency: item.router_data.request.destination_currency,
},
recurring: RecurringContract {
contract: Contract::Payout,
Expand Down Expand Up @@ -4077,7 +4089,7 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutF
Ok(Self::Card(Box::new(PayoutFulfillCardRequest {
amount: Amount {
value: item.amount.to_owned(),
currency: item.router_data.request.destination_currency.to_string(),
currency: item.router_data.request.destination_currency,
},
card: get_payout_card_details(&item.router_data.get_payout_method_data()?)
.map_or(
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const DEFAULT_FULFILLMENT_TIME: i64 = 15 * 60;
pub(crate) const NO_ERROR_MESSAGE: &str = "No error message";
pub(crate) const NO_ERROR_CODE: &str = "No error code";
pub(crate) const UNSUPPORTED_ERROR_MESSAGE: &str = "Unsupported response type";
pub(crate) const LOW_BALANCE_ERROR_MESSAGE: &str = "Insufficient balance in the payment method";
pub(crate) const CONNECTOR_UNAUTHORIZED_ERROR: &str = "Authentication Error from the connector";
pub(crate) const CANNOT_CONTINUE_AUTH: &str =
"Cannot continue with Authorization due to failed Liability Shift.";
Expand Down
Loading

0 comments on commit eabdeb7

Please sign in to comment.