mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat(connector): send metadata in payment authorize request for noon nmi cryptopay (#3325)
This commit is contained in:
@ -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
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use common_utils::pii;
|
||||
use masking::Secret;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -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,
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
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, PeekInterface, Secret};
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -395,9 +395,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 {
|
||||
@ -443,6 +469,12 @@ impl TryFrom<&NmiRouterData<&types::PaymentsAuthorizeRouterData>> for NmiPayment
|
||||
amount,
|
||||
currency: item.router_data.request.currency,
|
||||
payment_method,
|
||||
merchant_defined_field: item
|
||||
.router_data
|
||||
.request
|
||||
.metadata
|
||||
.as_ref()
|
||||
.map(NmiMerchantDefinedField::new),
|
||||
orderid: item.router_data.connector_request_reference_id.clone(),
|
||||
})
|
||||
}
|
||||
@ -556,6 +588,7 @@ impl TryFrom<&types::SetupMandateRouterData> for NmiPaymentsRequest {
|
||||
amount: 0.0,
|
||||
currency: item.request.currency,
|
||||
payment_method,
|
||||
merchant_defined_field: None,
|
||||
orderid: item.connector_request_reference_id.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
@ -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::{
|
||||
@ -28,7 +29,7 @@ use crate::{
|
||||
api::{self, ConnectorCommon, ConnectorCommonExt},
|
||||
ErrorResponse, Response,
|
||||
},
|
||||
utils::BytesExt,
|
||||
utils::{self, BytesExt},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -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)?;
|
||||
let response: Result<noon::NoonErrorResponse, Report<common_utils::errors::ParsingError>> =
|
||||
res.response.parse_struct("NoonErrorResponse");
|
||||
|
||||
Ok(ErrorResponse {
|
||||
match response {
|
||||
Ok(noon_error_response) => Ok(ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code: response.result_code.to_string(),
|
||||
message: response.class_description,
|
||||
reason: Some(response.message),
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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::{
|
||||
@ -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 {
|
||||
@ -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()? {
|
||||
|
||||
@ -11637,6 +11637,7 @@
|
||||
"PaymentMethodListResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"currency",
|
||||
"payment_methods",
|
||||
"mandate_payment",
|
||||
"show_surcharge_breakup_screen"
|
||||
@ -11648,6 +11649,9 @@
|
||||
"example": "https://www.google.com",
|
||||
"nullable": true
|
||||
},
|
||||
"currency": {
|
||||
"$ref": "#/components/schemas/Currency"
|
||||
},
|
||||
"payment_methods": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
||||
Reference in New Issue
Block a user