fix(connector): [Airwallex] Psync response (#1826)

Co-authored-by: SamraatBansal <55536657+SamraatBansal@users.noreply.github.com>
This commit is contained in:
Sakil Mostak
2023-08-01 15:14:02 +05:30
committed by GitHub
parent f492d0a943
commit 8f65819f12
2 changed files with 71 additions and 13 deletions

View File

@ -467,11 +467,11 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
res: Response, res: Response,
) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> { ) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> {
logger::debug!(payment_sync_response=?res); logger::debug!(payment_sync_response=?res);
let response: airwallex::AirwallexPaymentsResponse = res let response: airwallex::AirwallexPaymentsSyncResponse = res
.response .response
.parse_struct("airwallex PaymentsResponse") .parse_struct("airwallex AirwallexPaymentsSyncResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?; .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
types::RouterData::try_from(types::ResponseRouterData { types::PaymentsSyncRouterData::try_from(types::ResponseRouterData {
response, response,
data: data.clone(), data: data.clone(),
http_code: res.status_code, http_code: res.status_code,

View File

@ -10,7 +10,7 @@ use crate::{
core::errors, core::errors,
pii::Secret, pii::Secret,
services, services,
types::{self, api, storage::enums}, types::{self, api, storage::enums, PaymentsSyncData},
}; };
pub struct AirwallexAuthType { pub struct AirwallexAuthType {
@ -294,7 +294,7 @@ impl TryFrom<&types::PaymentsCancelRouterData> for AirwallexPaymentsCancelReques
} }
// PaymentsResponse // PaymentsResponse
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Default, Deserialize, PartialEq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum AirwallexPaymentStatus { pub enum AirwallexPaymentStatus {
Succeeded, Succeeded,
@ -307,13 +307,16 @@ pub enum AirwallexPaymentStatus {
Cancelled, Cancelled,
} }
fn get_payment_status(response: &AirwallexPaymentsResponse) -> enums::AttemptStatus { fn get_payment_status(
match response.status.clone() { status: &AirwallexPaymentStatus,
next_action: &Option<AirwallexPaymentsNextAction>,
) -> enums::AttemptStatus {
match status.clone() {
AirwallexPaymentStatus::Succeeded => enums::AttemptStatus::Charged, AirwallexPaymentStatus::Succeeded => enums::AttemptStatus::Charged,
AirwallexPaymentStatus::Failed => enums::AttemptStatus::Failure, AirwallexPaymentStatus::Failed => enums::AttemptStatus::Failure,
AirwallexPaymentStatus::Pending => enums::AttemptStatus::Pending, AirwallexPaymentStatus::Pending => enums::AttemptStatus::Pending,
AirwallexPaymentStatus::RequiresPaymentMethod => enums::AttemptStatus::PaymentMethodAwaited, AirwallexPaymentStatus::RequiresPaymentMethod => enums::AttemptStatus::PaymentMethodAwaited,
AirwallexPaymentStatus::RequiresCustomerAction => response.next_action.as_ref().map_or( AirwallexPaymentStatus::RequiresCustomerAction => next_action.as_ref().map_or(
enums::AttemptStatus::AuthenticationPending, enums::AttemptStatus::AuthenticationPending,
|next_action| match next_action.stage { |next_action| match next_action.stage {
AirwallexNextActionStage::WaitingDeviceDataCollection => { AirwallexNextActionStage::WaitingDeviceDataCollection => {
@ -328,6 +331,7 @@ fn get_payment_status(response: &AirwallexPaymentsResponse) -> enums::AttemptSta
AirwallexPaymentStatus::Cancelled => enums::AttemptStatus::Voided, AirwallexPaymentStatus::Cancelled => enums::AttemptStatus::Voided,
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")] #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum AirwallexNextActionStage { pub enum AirwallexNextActionStage {
@ -335,7 +339,7 @@ pub enum AirwallexNextActionStage {
WaitingUserInfoInput, WaitingUserInfoInput,
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct AirwallexRedirectFormData { pub struct AirwallexRedirectFormData {
#[serde(rename = "JWT")] #[serde(rename = "JWT")]
jwt: Option<String>, jwt: Option<String>,
@ -346,7 +350,7 @@ pub struct AirwallexRedirectFormData {
version: Option<String>, version: Option<String>,
} }
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct AirwallexPaymentsNextAction { pub struct AirwallexPaymentsNextAction {
url: Url, url: Url,
method: services::Method, method: services::Method,
@ -354,7 +358,7 @@ pub struct AirwallexPaymentsNextAction {
stage: AirwallexNextActionStage, stage: AirwallexNextActionStage,
} }
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] #[derive(Default, Debug, Clone, Deserialize, PartialEq)]
pub struct AirwallexPaymentsResponse { pub struct AirwallexPaymentsResponse {
status: AirwallexPaymentStatus, status: AirwallexPaymentStatus,
//Unique identifier for the PaymentIntent //Unique identifier for the PaymentIntent
@ -365,6 +369,17 @@ pub struct AirwallexPaymentsResponse {
next_action: Option<AirwallexPaymentsNextAction>, next_action: Option<AirwallexPaymentsNextAction>,
} }
#[derive(Default, Debug, Clone, Deserialize, PartialEq)]
pub struct AirwallexPaymentsSyncResponse {
status: AirwallexPaymentStatus,
//Unique identifier for the PaymentIntent
id: String,
amount: Option<f32>,
//ID of the PaymentConsent related to this PaymentIntent
payment_consent_id: Option<String>,
next_action: Option<AirwallexPaymentsNextAction>,
}
fn get_redirection_form( fn get_redirection_form(
response_url_data: AirwallexPaymentsNextAction, response_url_data: AirwallexPaymentsNextAction,
) -> Option<services::RedirectForm> { ) -> Option<services::RedirectForm> {
@ -415,7 +430,10 @@ impl<F, T>
) -> Result<Self, Self::Error> { ) -> Result<Self, Self::Error> {
let (status, redirection_data) = item.response.next_action.clone().map_or( let (status, redirection_data) = item.response.next_action.clone().map_or(
// If no next action is there, map the status and set redirection form as None // If no next action is there, map the status and set redirection form as None
(get_payment_status(&item.response), None), (
get_payment_status(&item.response.status, &item.response.next_action),
None,
),
|response_url_data| { |response_url_data| {
// If the connector sends a customer action response that is already under // If the connector sends a customer action response that is already under
// process from our end it can cause an infinite loop to break this this check // process from our end it can cause an infinite loop to break this this check
@ -447,7 +465,7 @@ impl<F, T>
} else { } else {
( (
//Build the redirect form and update the payment status //Build the redirect form and update the payment status
get_payment_status(&item.response), get_payment_status(&item.response.status, &item.response.next_action),
get_redirection_form(response_url_data), get_redirection_form(response_url_data),
) )
} }
@ -469,6 +487,46 @@ impl<F, T>
} }
} }
impl
TryFrom<
types::ResponseRouterData<
api::PSync,
AirwallexPaymentsSyncResponse,
PaymentsSyncData,
types::PaymentsResponseData,
>,
> for types::PaymentsSyncRouterData
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
item: types::ResponseRouterData<
api::PSync,
AirwallexPaymentsSyncResponse,
PaymentsSyncData,
types::PaymentsResponseData,
>,
) -> Result<Self, Self::Error> {
let status = get_payment_status(&item.response.status, &item.response.next_action);
let redirection_data = if let Some(redirect_url_data) = item.response.next_action {
get_redirection_form(redirect_url_data)
} else {
None
};
Ok(Self {
status,
reference_id: Some(item.response.id.clone()),
response: Ok(types::PaymentsResponseData::TransactionResponse {
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
redirection_data,
mandate_reference: None,
connector_metadata: None,
network_txn_id: None,
connector_response_reference_id: None,
}),
..item.data
})
}
}
// Type definition for RefundRequest // Type definition for RefundRequest
#[derive(Default, Debug, Serialize)] #[derive(Default, Debug, Serialize)]
pub struct AirwallexRefundRequest { pub struct AirwallexRefundRequest {