Skip to content
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

fix(webhooks): add support for updating mandate details in webhooks flow #6523

Merged
merged 16 commits into from
Nov 13, 2024
5 changes: 5 additions & 0 deletions crates/api_models/src/webhooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,3 +246,8 @@ pub struct ConnectorWebhookSecrets {
pub secret: Vec<u8>,
pub additional_secret: Option<masking::Secret<String>>,
}

#[derive(Debug, Clone, Serialize)]
pub struct ConnectorMandateDetails {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move this to domain models

pub connector_mandate_id: masking::Secret<String>,
}
122 changes: 121 additions & 1 deletion crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,10 @@ pub enum PaymentAttemptUpdate {
payment_method_id: Option<String>,
updated_by: String,
},
ConnectorMandateDetailUpdate {
connector_mandate_detail: Option<ConnectorMandateReferenceId>,
updated_by: String,
},
BlocklistUpdate {
status: storage_enums::AttemptStatus,
error_code: Option<Option<String>>,
Expand Down Expand Up @@ -628,6 +632,10 @@ pub enum PaymentAttemptUpdate {
// payment_method_id: Option<String>,
// updated_by: String,
// },
// ConnectorMandateDetailUpdate {
// connector_mandate_detail: Option<ConnectorMandateReferenceId>,
// updated_by: String,
// }
// BlocklistUpdate {
// status: storage_enums::AttemptStatus,
// error_code: Option<Option<String>>,
Expand Down Expand Up @@ -1393,7 +1401,63 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
// customer_acceptance: None,
// card_network: None,
// },
// PaymentAttemptUpdate::PaymentMethodDetailsUpdate {
// PaymentAttemptUpdate::ConnectorMandateDetailUpdate {
// connector_mandate_detail,
// updated_by,
// } => Self {
// payment_method_id: None,
// modified_at: common_utils::date_time::now(),
// updated_by,
// amount: None,
// net_amount: None,
// currency: None,
// status: None,
// connector_transaction_id: None,
// amount_to_capture: None,
// connector: None,
// authentication_type: None,
// payment_method: None,
// error_message: None,
// cancellation_reason: None,
// mandate_id: None,
// browser_info: None,
// payment_token: None,
// error_code: None,
// connector_metadata: None,
// payment_method_data: None,
// payment_method_type: None,
// payment_experience: None,
// business_sub_label: None,
// straight_through_algorithm: None,
// preprocessing_step_id: None,
// error_reason: None,
// capture_method: None,
// connector_response_reference_id: None,
// multiple_capture_count: None,
// surcharge_amount: None,
// tax_amount: None,
// amount_capturable: None,
// merchant_connector_id: None,
// authentication_data: None,
// encoded_data: None,
// unified_code: None,
// unified_message: None,
// external_three_ds_authentication_attempted: None,
// authentication_connector: None,
// authentication_id: None,
// fingerprint_id: None,
// payment_method_billing_address_id: None,
// charge_id: None,
// client_source: None,
// client_version: None,
// customer_acceptance: None,
// card_network: None,
// shipping_cost: None,
// order_tax_amount: None,
// connector_transaction_data: None,
// connector_mandate_detail,
// },
// PaymentAttemptUpdate::ConnectorMandateDetailUpdate {
// payment_method_id,
// updated_by,
// } => Self {
Expand Down Expand Up @@ -2394,6 +2458,62 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
connector_transaction_data: None,
connector_mandate_detail: None,
},
PaymentAttemptUpdate::ConnectorMandateDetailUpdate {
connector_mandate_detail,
updated_by,
} => Self {
payment_method_id: None,
modified_at: common_utils::date_time::now(),
updated_by,
amount: None,
net_amount: None,
currency: None,
status: None,
connector_transaction_id: None,
amount_to_capture: None,
connector: None,
authentication_type: None,
payment_method: None,
error_message: None,
cancellation_reason: None,
mandate_id: None,
browser_info: None,
payment_token: None,
error_code: None,
connector_metadata: None,
payment_method_data: None,
payment_method_type: None,
payment_experience: None,
business_sub_label: None,
straight_through_algorithm: None,
preprocessing_step_id: None,
error_reason: None,
capture_method: None,
connector_response_reference_id: None,
multiple_capture_count: None,
surcharge_amount: None,
tax_amount: None,
amount_capturable: None,
merchant_connector_id: None,
authentication_data: None,
encoded_data: None,
unified_code: None,
unified_message: None,
external_three_ds_authentication_attempted: None,
authentication_connector: None,
authentication_id: None,
fingerprint_id: None,
payment_method_billing_address_id: None,
charge_id: None,
client_source: None,
client_version: None,
customer_acceptance: None,
card_network: None,
shipping_cost: None,
order_tax_amount: None,
connector_transaction_data: None,
connector_mandate_detail,
},
PaymentAttemptUpdate::PaymentMethodDetailsUpdate {
payment_method_id,
updated_by,
Expand Down
44 changes: 43 additions & 1 deletion crates/hyperswitch_connectors/src/connectors/fiuu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use masking::{ExposeInterface, PeekInterface, Secret};
use reqwest::multipart::Form;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use transformers::{self as fiuu, FiuuWebhooksResponse};
use transformers::{self as fiuu, ExtraParameters, FiuuWebhooksResponse};

use crate::{
constants::headers,
Expand Down Expand Up @@ -890,4 +890,46 @@ impl webhooks::IncomingWebhook for Fiuu {
}
}
}

fn get_mandate_details(
&self,
request: &webhooks::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Option<api_models::webhooks::ConnectorMandateDetails>, errors::ConnectorError>
{
let header = utils::get_header_key_value("content-type", request.headers)?;
let payload: FiuuWebhooksResponse = if header == "application/x-www-form-urlencoded" {
serde_urlencoded::from_bytes::<FiuuWebhooksResponse>(request.body)
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?
} else {
request
.body
.parse_struct("fiuu::FiuuWebhooksResponse")
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
.change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?

};
match payload.clone() {
FiuuWebhooksResponse::FiuuWebhookPaymentResponse(webhook_payment_response) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can directly parse it into FiuuWebhookPaymentResponse

let mandate_reference = webhook_payment_response.extra_parameters.as_ref().and_then(|extra_p| {
let mandate_token: Result<ExtraParameters, _> = serde_json::from_str(extra_p);
match mandate_token {
Ok(token) => {
token.token.as_ref().map(|token| api_models::webhooks::ConnectorMandateDetails {
connector_mandate_id:token.clone(),
})
}
Err(err) => {
router_env::logger::warn!(
"Failed to convert 'extraP' from fiuu webhook response to fiuu::ExtraParameters. \
Input: '{}', Error: {}",
extra_p,
err
);
None
}
}
});
Ok(mandate_reference)
}
FiuuWebhooksResponse::FiuuWebhookRefundResponse(_webhook_refund_response) => Ok(None),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ pub struct NonThreeDSResponseData {

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ExtraParameters {
token: Option<Secret<String>>,
pub token: Option<Secret<String>>,
}

impl<F>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,10 @@ pub enum PaymentAttemptUpdate {
payment_method_id: Option<String>,
updated_by: String,
},
ConnectorMandateDetailUpdate {
connector_mandate_detail: Option<ConnectorMandateReferenceId>,
updated_by: String,
},
VoidUpdate {
status: storage_enums::AttemptStatus,
cancellation_reason: Option<String>,
Expand Down Expand Up @@ -992,6 +996,13 @@ impl PaymentAttemptUpdate {
error_message,
updated_by,
},
Self::ConnectorMandateDetailUpdate {
connector_mandate_detail,
updated_by,
} => DieselPaymentAttemptUpdate::ConnectorMandateDetailUpdate {
connector_mandate_detail,
updated_by,
},
Self::PaymentMethodDetailsUpdate {
payment_method_id,
updated_by,
Expand Down
9 changes: 9 additions & 0 deletions crates/hyperswitch_interfaces/src/webhooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,13 @@ pub trait IncomingWebhook: ConnectorCommon + Sync {
)
.into())
}

/// fn get_mandate_details
fn get_mandate_details(
&self,
_request: &IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Option<api_models::webhooks::ConnectorMandateDetails>, errors::ConnectorError>
{
Ok(None)
}
}
Loading
Loading