-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(connector): [Iatapay] refactor authorize flow and fix payment status mapping #2409
Changes from 14 commits
60a2906
8bf23c1
6b047db
f9920fc
9289539
ed287a9
7ece58b
50994d9
6c9114d
a151696
270124f
b075442
ee60437
561407b
bddeb7c
04014be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,9 @@ use masking::{Secret, SwitchStrategy}; | |
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::{ | ||
connector::utils::{self, PaymentsAuthorizeRequestData, RefundsRequestData, RouterData}, | ||
connector::utils::{ | ||
self as connector_util, PaymentsAuthorizeRequestData, RefundsRequestData, RouterData, | ||
}, | ||
consts, | ||
core::errors, | ||
services, | ||
|
@@ -53,7 +55,7 @@ impl<T> | |
), | ||
) -> Result<Self, Self::Error> { | ||
Ok(Self { | ||
amount: utils::to_currency_base_unit_asf64(_amount, _currency)?, | ||
amount: connector_util::to_currency_base_unit_asf64(_amount, _currency)?, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
router_data: item, | ||
}) | ||
} | ||
|
@@ -136,7 +138,6 @@ impl | |
let payment_method = item.router_data.payment_method; | ||
let country = match payment_method { | ||
PaymentMethod::Upi => "IN".to_string(), | ||
|
||
PaymentMethod::Card | ||
| PaymentMethod::CardRedirect | ||
| PaymentMethod::PayLater | ||
|
@@ -154,7 +155,19 @@ impl | |
api::PaymentMethodData::Upi(upi_data) => upi_data.vpa_id.map(|id| PayerInfo { | ||
token_id: id.switch_strategy(), | ||
}), | ||
_ => None, | ||
api::PaymentMethodData::Card(_) | ||
| api::PaymentMethodData::CardRedirect(_) | ||
| api::PaymentMethodData::Wallet(_) | ||
| api::PaymentMethodData::PayLater(_) | ||
| api::PaymentMethodData::BankRedirect(_) | ||
| api::PaymentMethodData::BankDebit(_) | ||
| api::PaymentMethodData::BankTransfer(_) | ||
| api::PaymentMethodData::Crypto(_) | ||
| api::PaymentMethodData::MandatePayment | ||
| api::PaymentMethodData::Reward | ||
| api::PaymentMethodData::Voucher(_) | ||
| api::PaymentMethodData::GiftCard(_) | ||
| api::PaymentMethodData::CardToken(_) => None, | ||
}; | ||
let payload = Self { | ||
merchant_id: IatapayAuthType::try_from(&item.router_data.connector_auth_type)? | ||
|
@@ -212,15 +225,9 @@ pub enum IatapayPaymentStatus { | |
Initiated, | ||
Authorized, | ||
Settled, | ||
Tobeinvestigated, | ||
Blocked, | ||
Cleared, | ||
Failed, | ||
Locked, | ||
#[serde(rename = "UNEXPECTED SETTLED")] | ||
UnexpectedSettled, | ||
#[serde(other)] | ||
Unknown, | ||
} | ||
|
||
impl From<IatapayPaymentStatus> for enums::AttemptStatus { | ||
|
@@ -230,7 +237,6 @@ impl From<IatapayPaymentStatus> for enums::AttemptStatus { | |
IatapayPaymentStatus::Failed | IatapayPaymentStatus::UnexpectedSettled => Self::Failure, | ||
IatapayPaymentStatus::Created => Self::AuthenticationPending, | ||
IatapayPaymentStatus::Initiated => Self::Pending, | ||
_ => Self::Voided, | ||
} | ||
} | ||
} | ||
|
@@ -276,7 +282,7 @@ fn get_iatpay_response( | |
errors::ConnectorError, | ||
> { | ||
let status = enums::AttemptStatus::from(response.status); | ||
let error = if status == enums::AttemptStatus::Failure { | ||
let error = if connector_util::is_payment_failure(status) { | ||
Some(types::ErrorResponse { | ||
code: response | ||
.failure_code | ||
|
@@ -433,11 +439,31 @@ impl TryFrom<types::RefundsResponseRouterData<api::Execute, RefundResponse>> | |
fn try_from( | ||
item: types::RefundsResponseRouterData<api::Execute, RefundResponse>, | ||
) -> Result<Self, Self::Error> { | ||
let refund_status = enums::RefundStatus::from(item.response.status); | ||
|
||
Ok(Self { | ||
response: Ok(types::RefundsResponseData { | ||
connector_refund_id: item.response.iata_refund_id.to_string(), | ||
refund_status: enums::RefundStatus::from(item.response.status), | ||
}), | ||
response: if connector_util::is_refund_failure(refund_status) { | ||
Err(types::ErrorResponse { | ||
code: item | ||
.response | ||
.failure_code | ||
.unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()), | ||
message: item | ||
.response | ||
.failure_details | ||
.clone() | ||
.unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()), | ||
reason: item.response.failure_details, | ||
status_code: item.http_code, | ||
attempt_status: None, | ||
connector_transaction_id: Some(item.response.iata_refund_id.clone()), | ||
}) | ||
} else { | ||
Ok(types::RefundsResponseData { | ||
connector_refund_id: item.response.iata_refund_id.to_string(), | ||
refund_status, | ||
}) | ||
}, | ||
..item.data | ||
}) | ||
} | ||
|
@@ -450,11 +476,30 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, RefundResponse>> | |
fn try_from( | ||
item: types::RefundsResponseRouterData<api::RSync, RefundResponse>, | ||
) -> Result<Self, Self::Error> { | ||
let refund_status = enums::RefundStatus::from(item.response.status); | ||
Ok(Self { | ||
response: Ok(types::RefundsResponseData { | ||
connector_refund_id: item.response.iata_refund_id.to_string(), | ||
refund_status: enums::RefundStatus::from(item.response.status), | ||
}), | ||
response: if connector_util::is_refund_failure(refund_status) { | ||
Err(types::ErrorResponse { | ||
code: item | ||
.response | ||
.failure_code | ||
.unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()), | ||
message: item | ||
.response | ||
.failure_details | ||
.clone() | ||
.unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()), | ||
reason: item.response.failure_details, | ||
status_code: item.http_code, | ||
attempt_status: None, | ||
connector_transaction_id: Some(item.response.iata_refund_id.clone()), | ||
}) | ||
} else { | ||
Ok(types::RefundsResponseData { | ||
connector_refund_id: item.response.iata_refund_id.to_string(), | ||
refund_status, | ||
}) | ||
}, | ||
..item.data | ||
}) | ||
} | ||
|
@@ -473,3 +518,90 @@ pub struct IatapayAccessTokenErrorResponse { | |
pub error: String, | ||
pub path: String, | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct IatapayPaymentWebhookBody { | ||
pub status: IatapayWebhookStatus, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. incase of payment failure error_message, error_code and error_reason should be captured There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we are already doing this for payments! |
||
pub iata_payment_id: String, | ||
pub merchant_payment_id: Option<String>, | ||
pub failure_code: Option<String>, | ||
pub failure_details: Option<String>, | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct IatapayRefundWebhookBody { | ||
pub status: IatapayRefundWebhookStatus, | ||
pub iata_refund_id: String, | ||
pub merchant_refund_id: Option<String>, | ||
pub failure_code: Option<String>, | ||
pub failure_details: Option<String>, | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
pub enum IatapayWebhookResponse { | ||
IatapayPaymentWebhookBody(IatapayPaymentWebhookBody), | ||
IatapayRefundWebhookBody(IatapayRefundWebhookBody), | ||
} | ||
|
||
impl TryFrom<IatapayWebhookResponse> for api::IncomingWebhookEvent { | ||
type Error = error_stack::Report<errors::ConnectorError>; | ||
fn try_from(payload: IatapayWebhookResponse) -> CustomResult<Self, errors::ConnectorError> { | ||
match payload { | ||
IatapayWebhookResponse::IatapayPaymentWebhookBody(wh_body) => match wh_body.status { | ||
IatapayWebhookStatus::Authorized | IatapayWebhookStatus::Settled => { | ||
Ok(Self::PaymentIntentSuccess) | ||
} | ||
IatapayWebhookStatus::Initiated => Ok(Self::PaymentIntentProcessing), | ||
IatapayWebhookStatus::Failed => Ok(Self::PaymentIntentFailure), | ||
IatapayWebhookStatus::Created | ||
| IatapayWebhookStatus::Cleared | ||
| IatapayWebhookStatus::Tobeinvestigated | ||
| IatapayWebhookStatus::Blocked | ||
| IatapayWebhookStatus::UnexpectedSettled | ||
| IatapayWebhookStatus::Unknown => Ok(Self::EventNotSupported), | ||
}, | ||
IatapayWebhookResponse::IatapayRefundWebhookBody(wh_body) => match wh_body.status { | ||
IatapayRefundWebhookStatus::Authorized | IatapayRefundWebhookStatus::Settled => { | ||
Ok(Self::RefundSuccess) | ||
} | ||
IatapayRefundWebhookStatus::Failed => Ok(Self::RefundFailure), | ||
IatapayRefundWebhookStatus::Created | ||
| IatapayRefundWebhookStatus::Locked | ||
| IatapayRefundWebhookStatus::Initiated | ||
| IatapayRefundWebhookStatus::Unknown => Ok(Self::EventNotSupported), | ||
}, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(rename_all = "UPPERCASE")] | ||
pub enum IatapayWebhookStatus { | ||
Created, | ||
Initiated, | ||
Authorized, | ||
Settled, | ||
Cleared, | ||
Failed, | ||
Tobeinvestigated, | ||
Blocked, | ||
#[serde(rename = "UNEXPECTED SETTLED")] | ||
UnexpectedSettled, | ||
#[serde(other)] | ||
Unknown, | ||
} | ||
|
||
#[derive(Debug, Serialize, Deserialize)] | ||
#[serde(rename_all = "UPPERCASE")] | ||
pub enum IatapayRefundWebhookStatus { | ||
Created, | ||
Initiated, | ||
Authorized, | ||
Settled, | ||
Failed, | ||
Locked, | ||
#[serde(other)] | ||
Unknown, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be RefundId not PaymentId