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

feat(connector): [Bluesnap] Metadata to connector metadata mapping #3331

Merged
merged 14 commits into from
Jan 30, 2024
57 changes: 56 additions & 1 deletion crates/router/src/connector/bluesnap/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use api_models::{enums as api_enums, payments};
use base64::Engine;
use common_utils::{
Expand All @@ -8,6 +10,7 @@ use common_utils::{
use error_stack::{IntoReport, ResultExt};
use masking::{ExposeInterface, PeekInterface};
use serde::{Deserialize, Serialize};
use serde_json::Value;

use crate::{
connector::utils::{
Expand Down Expand Up @@ -63,6 +66,21 @@ pub struct BluesnapPaymentsRequest {
transaction_fraud_info: Option<TransactionFraudInfo>,
card_holder_info: Option<BluesnapCardHolderInfo>,
merchant_transaction_id: Option<String>,
transaction_meta_data: Option<BluesnapMetadata>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BluesnapMetadata {
meta_data: Vec<RequestMetadata>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RequestMetadata {
meta_key: String,
meta_value: String,
is_visible: String, //Property controlling whether the transaction metadata is visible in the invoice (Y) or hidden (N).
}

#[derive(Debug, Serialize)]
Expand Down Expand Up @@ -241,6 +259,13 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for Blues
Some(enums::CaptureMethod::Manual) => BluesnapTxnType::AuthOnly,
_ => BluesnapTxnType::AuthCapture,
};
let transaction_meta_data = match item.router_data.request.metadata.as_ref() {
Some(metadata) => Some(BluesnapMetadata {
meta_data: Vec::<RequestMetadata>::foreign_try_from(metadata.peek().to_owned())?,
}),
None => None,
};

let (payment_method, card_holder_info) = match item
.router_data
.request
Expand Down Expand Up @@ -405,6 +430,7 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for Blues
}),
card_holder_info,
merchant_transaction_id: Some(item.router_data.connector_request_reference_id.clone()),
transaction_meta_data,
})
}
}
Expand Down Expand Up @@ -569,6 +595,7 @@ pub struct BluesnapCompletePaymentsRequest {
transaction_fraud_info: Option<TransactionFraudInfo>,
card_holder_info: Option<BluesnapCardHolderInfo>,
merchant_transaction_id: Option<String>,
transaction_meta_data: Option<BluesnapMetadata>,
}

impl TryFrom<&BluesnapRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
Expand All @@ -590,6 +617,13 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
.parse_value("BluesnapRedirectionResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

let transaction_meta_data = match item.router_data.request.metadata.as_ref() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to pass meta data in complete authorize as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, because transaction call to Bluesnap for 3ds payments happen through complete authorize

Some(metadata) => Some(BluesnapMetadata {
meta_data: Vec::<RequestMetadata>::foreign_try_from(metadata.peek().to_owned())?,
}),
None => None,
};

let pf_token = item
.router_data
.request
Expand Down Expand Up @@ -637,6 +671,7 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsCompleteAuthorizeRouterData>>
)?,
merchant_transaction_id: Some(item.router_data.connector_request_reference_id.clone()),
pf_token,
transaction_meta_data,
})
}
}
Expand Down Expand Up @@ -1021,7 +1056,7 @@ pub struct BluesnapWebhookObjectResource {
reversal_ref_num: Option<String>,
}

impl TryFrom<BluesnapWebhookObjectResource> for serde_json::Value {
impl TryFrom<BluesnapWebhookObjectResource> for Value {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(details: BluesnapWebhookObjectResource) -> Result<Self, Self::Error> {
let (card_transaction_type, processing_status, transaction_id) = match details
Expand Down Expand Up @@ -1118,3 +1153,23 @@ impl From<ErrorDetails> for utils::ErrorCodeAndMessage {
}
}
}

impl ForeignTryFrom<Value> for Vec<RequestMetadata> {
type Error = error_stack::Report<errors::ConnectorError>;
fn foreign_try_from(metadata: Value) -> Result<Self, Self::Error> {
let hashmap: HashMap<String, String> = serde_json::from_str(&metadata.to_string())
.ok()
.ok_or(errors::ConnectorError::RequestEncodingFailedWithReason(
"Metadata is not in the expected format".to_string(),
))?;
let mut vector: Self = Self::new();
for (key, value) in hashmap {
vector.push(RequestMetadata {
meta_key: key,
meta_value: value,
is_visible: "Y".to_owned(),
AkshayaFoiger marked this conversation as resolved.
Show resolved Hide resolved
});
}
Ok(vector)
}
}
Loading