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): send metadata in payment authorize request for noon nmi cryptopay #3325

Merged
merged 7 commits into from
Feb 6, 2024
2 changes: 1 addition & 1 deletion crates/api_models/src/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ pub struct PaymentMethodListResponse {
pub redirect_url: Option<String>,

/// currency of the Payment to be done
#[schema(example = "USD")]
#[schema(example = "USD", value_type = Currency)]
pub currency: Option<api_enums::Currency>,

/// Information about the payment method
Expand Down
3 changes: 3 additions & 0 deletions crates/router/src/connector/cryptopay/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use common_utils::pii;
use masking::Secret;
use reqwest::Url;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -47,6 +48,7 @@ pub struct CryptopayPaymentsRequest {
pay_currency: String,
success_redirect_url: Option<String>,
unsuccess_redirect_url: Option<String>,
metadata: Option<pii::SecretSerdeValue>,
custom_id: String,
}

Expand All @@ -66,6 +68,7 @@ impl TryFrom<&CryptopayRouterData<&types::PaymentsAuthorizeRouterData>>
pay_currency,
success_redirect_url: item.router_data.request.router_return_url.clone(),
unsuccess_redirect_url: item.router_data.request.router_return_url.clone(),
metadata: item.router_data.request.metadata.clone(),
custom_id: item.router_data.connector_request_reference_id.clone(),
})
}
Expand Down
37 changes: 35 additions & 2 deletions crates/router/src/connector/nmi/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use api_models::webhooks;
use cards::CardNumber;
use common_utils::{errors::CustomResult, ext_traits::XmlExt};
use common_utils::{errors::CustomResult, ext_traits::XmlExt, pii};
use error_stack::{IntoReport, Report, ResultExt};
use masking::{ExposeInterface, Secret};
use masking::{ExposeInterface, PeekInterface, Secret};
use serde::{Deserialize, Serialize};

use crate::{
Expand Down Expand Up @@ -403,9 +403,35 @@ pub struct NmiPaymentsRequest {
currency: enums::Currency,
#[serde(flatten)]
payment_method: PaymentMethod,
#[serde(flatten)]
merchant_defined_field: Option<NmiMerchantDefinedField>,
orderid: String,
}

#[derive(Debug, Serialize)]
pub struct NmiMerchantDefinedField {
#[serde(flatten)]
inner: std::collections::BTreeMap<String, Secret<String>>,
}

impl NmiMerchantDefinedField {
pub fn new(metadata: &pii::SecretSerdeValue) -> Self {
let metadata_as_string = metadata.peek().to_string();
let hash_map: std::collections::BTreeMap<String, serde_json::Value> =
serde_json::from_str(&metadata_as_string).unwrap_or(std::collections::BTreeMap::new());
let inner = hash_map
.into_iter()
.enumerate()
.map(|(index, (hs_key, hs_value))| {
let nmi_key = format!("merchant_defined_field_{}", index + 1);
let nmi_value = format!("{hs_key}={hs_value}");
(nmi_key, Secret::new(nmi_value))
})
.collect();
Self { inner }
}
}

#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum PaymentMethod {
Expand Down Expand Up @@ -451,6 +477,12 @@ impl TryFrom<&NmiRouterData<&types::PaymentsAuthorizeRouterData>> for NmiPayment
amount,
currency: item.router_data.request.currency,
payment_method,
merchant_defined_field: item
hrithikesh026 marked this conversation as resolved.
Show resolved Hide resolved
.router_data
.request
.metadata
.as_ref()
.map(NmiMerchantDefinedField::new),
orderid: item.router_data.connector_request_reference_id.clone(),
})
}
Expand Down Expand Up @@ -564,6 +596,7 @@ impl TryFrom<&types::SetupMandateRouterData> for NmiPaymentsRequest {
amount: 0.0,
currency: item.request.currency,
payment_method,
merchant_defined_field: None,
hrithikesh026 marked this conversation as resolved.
Show resolved Hide resolved
orderid: item.connector_request_reference_id.clone(),
})
}
Expand Down
35 changes: 20 additions & 15 deletions crates/router/src/connector/noon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use std::fmt::Debug;
use base64::Engine;
use common_utils::{crypto, ext_traits::ByteSliceExt, request::RequestContent};
use diesel_models::enums;
use error_stack::{IntoReport, ResultExt};
use error_stack::{IntoReport, Report, ResultExt};
use masking::PeekInterface;
use router_env::logger;
use transformers as noon;

use crate::{
Expand All @@ -28,7 +29,7 @@ use crate::{
api::{self, ConnectorCommon, ConnectorCommonExt},
ErrorResponse, Response,
},
utils::BytesExt,
utils::{self, BytesExt},
};

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -127,19 +128,23 @@ impl ConnectorCommon for Noon {
&self,
res: Response,
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
let response: noon::NoonErrorResponse = res
.response
.parse_struct("NoonErrorResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

Ok(ErrorResponse {
status_code: res.status_code,
code: response.result_code.to_string(),
message: response.class_description,
reason: Some(response.message),
attempt_status: None,
connector_transaction_id: None,
})
let response: Result<noon::NoonErrorResponse, Report<common_utils::errors::ParsingError>> =
res.response.parse_struct("NoonErrorResponse");

match response {
Ok(noon_error_response) => Ok(ErrorResponse {
status_code: res.status_code,
code: consts::NO_ERROR_CODE.to_string(),
message: noon_error_response.class_description,
reason: Some(noon_error_response.message),
attempt_status: None,
connector_transaction_id: None,
}),
Err(error_message) => {
logger::error!(deserialization_error =? error_message);
utils::handle_json_response_deserialization_failure(res, "noon".to_owned())
}
}
}
}

Expand Down
40 changes: 39 additions & 1 deletion crates/router/src/connector/noon/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use common_utils::pii;
use error_stack::ResultExt;
use masking::Secret;
use masking::{PeekInterface, Secret};
use serde::{Deserialize, Serialize};

use crate::{
Expand Down Expand Up @@ -67,9 +67,46 @@ pub struct NoonOrder {
reference: String,
//Short description of the order.
name: String,
nvp: Option<NoonOrderNvp>,
ip_address: Option<Secret<String, pii::IpAddress>>,
}

#[derive(Debug, Serialize)]
pub struct NoonOrderNvp {
#[serde(flatten)]
inner: std::collections::BTreeMap<String, Secret<String>>,
}

fn get_value_as_string(value: &serde_json::Value) -> String {
match value {
serde_json::Value::String(string) => string.to_owned(),
serde_json::Value::Null
| serde_json::Value::Bool(_)
| serde_json::Value::Number(_)
| serde_json::Value::Array(_)
| serde_json::Value::Object(_) => value.to_string(),
}
}

impl NoonOrderNvp {
pub fn new(metadata: &pii::SecretSerdeValue) -> Self {
let metadata_as_string = metadata.peek().to_string();
let hash_map: std::collections::BTreeMap<String, serde_json::Value> =
serde_json::from_str(&metadata_as_string).unwrap_or(std::collections::BTreeMap::new());
let inner = hash_map
.into_iter()
.enumerate()
.map(|(index, (hs_key, hs_value))| {
let noon_key = format!("{}", index + 1);
// to_string() function on serde_json::Value returns a string with "" quotes. Noon doesn't allow this. Hence get_value_as_string function
let noon_value = format!("{hs_key}={}", get_value_as_string(&hs_value));
(noon_key, Secret::new(noon_value))
})
.collect();
Self { inner }
}
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum NoonPaymentActions {
Expand Down Expand Up @@ -365,6 +402,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
category,
reference: item.connector_request_reference_id.clone(),
name,
nvp: item.request.metadata.as_ref().map(NoonOrderNvp::new),
ip_address,
};
let payment_action = if item.request.is_auto_capture()? {
Expand Down
4 changes: 4 additions & 0 deletions openapi/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -11637,6 +11637,7 @@
"PaymentMethodListResponse": {
"type": "object",
"required": [
"currency",
"payment_methods",
"mandate_payment",
"show_surcharge_breakup_screen"
Expand All @@ -11648,6 +11649,9 @@
"example": "https://www.google.com",
"nullable": true
},
"currency": {
"$ref": "#/components/schemas/Currency"
},
"payment_methods": {
"type": "array",
"items": {
Expand Down
Loading