mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
fix(core): fixed type metadata to accept other udf fields as well (#321)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -321,6 +321,7 @@ name = "api_models"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"common_utils",
|
"common_utils",
|
||||||
|
"error-stack",
|
||||||
"frunk",
|
"frunk",
|
||||||
"frunk_core",
|
"frunk_core",
|
||||||
"masking",
|
"masking",
|
||||||
|
|||||||
@ -6,6 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
error-stack = "0.2.4"
|
||||||
frunk = "0.4.1"
|
frunk = "0.4.1"
|
||||||
frunk_core = "0.4.1"
|
frunk_core = "0.4.1"
|
||||||
serde = { version = "1.0.145", features = ["derive"] }
|
serde = { version = "1.0.145", features = ["derive"] }
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::num::NonZeroI64;
|
use std::num::NonZeroI64;
|
||||||
|
|
||||||
use common_utils::pii;
|
use common_utils::{errors, ext_traits::Encode, pii};
|
||||||
use masking::{PeekInterface, Secret};
|
use masking::{PeekInterface, Secret};
|
||||||
use router_derive::Setter;
|
use router_derive::Setter;
|
||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
@ -15,11 +15,6 @@ pub enum PaymentOp {
|
|||||||
Confirm,
|
Confirm,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)]
|
|
||||||
pub struct Metadata {
|
|
||||||
pub order_details: OrderDetails,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct PaymentsRequest {
|
pub struct PaymentsRequest {
|
||||||
@ -53,7 +48,7 @@ pub struct PaymentsRequest {
|
|||||||
pub billing: Option<Address>,
|
pub billing: Option<Address>,
|
||||||
pub statement_descriptor_name: Option<String>,
|
pub statement_descriptor_name: Option<String>,
|
||||||
pub statement_descriptor_suffix: Option<String>,
|
pub statement_descriptor_suffix: Option<String>,
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<Metadata>,
|
||||||
pub client_secret: Option<String>,
|
pub client_secret: Option<String>,
|
||||||
pub mandate_data: Option<MandateData>,
|
pub mandate_data: Option<MandateData>,
|
||||||
pub mandate_id: Option<String>,
|
pub mandate_id: Option<String>,
|
||||||
@ -561,21 +556,25 @@ impl From<&VerifyRequest> for MandateValidationFields {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PaymentsRequest> for PaymentsResponse {
|
impl TryFrom<PaymentsRequest> for PaymentsResponse {
|
||||||
fn from(item: PaymentsRequest) -> Self {
|
type Error = error_stack::Report<errors::ParsingError>;
|
||||||
|
fn try_from(item: PaymentsRequest) -> Result<Self, Self::Error> {
|
||||||
let payment_id = match item.payment_id {
|
let payment_id = match item.payment_id {
|
||||||
Some(PaymentIdType::PaymentIntentId(id)) => Some(id),
|
Some(PaymentIdType::PaymentIntentId(id)) => Some(id),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
let metadata = item
|
||||||
Self {
|
.metadata
|
||||||
|
.map(|a| Encode::<Metadata>::encode_to_value(&a))
|
||||||
|
.transpose()?;
|
||||||
|
Ok(Self {
|
||||||
payment_id,
|
payment_id,
|
||||||
merchant_id: item.merchant_id,
|
merchant_id: item.merchant_id,
|
||||||
setup_future_usage: item.setup_future_usage,
|
setup_future_usage: item.setup_future_usage,
|
||||||
off_session: item.off_session,
|
off_session: item.off_session,
|
||||||
shipping: item.shipping,
|
shipping: item.shipping,
|
||||||
billing: item.billing,
|
billing: item.billing,
|
||||||
metadata: item.metadata,
|
metadata,
|
||||||
capture_method: item.capture_method,
|
capture_method: item.capture_method,
|
||||||
payment_method: item.payment_method,
|
payment_method: item.payment_method,
|
||||||
capture_on: item.capture_on,
|
capture_on: item.capture_on,
|
||||||
@ -592,7 +591,7 @@ impl From<PaymentsRequest> for PaymentsResponse {
|
|||||||
statement_descriptor_suffix: item.statement_descriptor_suffix,
|
statement_descriptor_suffix: item.statement_descriptor_suffix,
|
||||||
mandate_data: item.mandate_data,
|
mandate_data: item.mandate_data,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,12 +758,19 @@ pub enum SupportedWallets {
|
|||||||
Gpay,
|
Gpay,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct OrderDetails {
|
pub struct OrderDetails {
|
||||||
pub product_name: String,
|
pub product_name: String,
|
||||||
pub quantity: u16,
|
pub quantity: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct Metadata {
|
||||||
|
pub order_details: Option<OrderDetails>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub data: serde_json::Value,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct PaymentsSessionRequest {
|
pub struct PaymentsSessionRequest {
|
||||||
pub payment_id: String,
|
pub payment_id: String,
|
||||||
|
|||||||
@ -132,7 +132,7 @@ pub struct StripePaymentIntentRequest {
|
|||||||
pub billing_details: Option<StripeBillingDetails>,
|
pub billing_details: Option<StripeBillingDetails>,
|
||||||
pub statement_descriptor: Option<String>,
|
pub statement_descriptor: Option<String>,
|
||||||
pub statement_descriptor_suffix: Option<String>,
|
pub statement_descriptor_suffix: Option<String>,
|
||||||
pub metadata: Option<Value>,
|
pub metadata: Option<api_models::payments::Metadata>,
|
||||||
pub client_secret: Option<pii::Secret<String>>,
|
pub client_secret: Option<pii::Secret<String>>,
|
||||||
pub payment_method_options: Option<StripePaymentMethodOptions>,
|
pub payment_method_options: Option<StripePaymentMethodOptions>,
|
||||||
}
|
}
|
||||||
@ -277,6 +277,7 @@ pub struct StripePaymentIntentResponse {
|
|||||||
pub customer: Option<String>,
|
pub customer: Option<String>,
|
||||||
pub refunds: Option<Vec<refunds::RefundResponse>>,
|
pub refunds: Option<Vec<refunds::RefundResponse>>,
|
||||||
pub mandate_id: Option<String>,
|
pub mandate_id: Option<String>,
|
||||||
|
pub metadata: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<payments::PaymentsResponse> for StripePaymentIntentResponse {
|
impl From<payments::PaymentsResponse> for StripePaymentIntentResponse {
|
||||||
@ -294,6 +295,7 @@ impl From<payments::PaymentsResponse> for StripePaymentIntentResponse {
|
|||||||
id: resp.payment_id,
|
id: resp.payment_id,
|
||||||
refunds: resp.refunds,
|
refunds: resp.refunds,
|
||||||
mandate_id: resp.mandate_id,
|
mandate_id: resp.mandate_id,
|
||||||
|
metadata: resp.metadata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -122,7 +122,7 @@ pub struct StripeSetupIntentRequest {
|
|||||||
pub billing_details: Option<StripeBillingDetails>,
|
pub billing_details: Option<StripeBillingDetails>,
|
||||||
pub statement_descriptor: Option<String>,
|
pub statement_descriptor: Option<String>,
|
||||||
pub statement_descriptor_suffix: Option<String>,
|
pub statement_descriptor_suffix: Option<String>,
|
||||||
pub metadata: Option<Value>,
|
pub metadata: Option<api_models::payments::Metadata>,
|
||||||
pub client_secret: Option<pii::Secret<String>>,
|
pub client_secret: Option<pii::Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -171,7 +171,7 @@ where
|
|||||||
FData: Send,
|
FData: Send,
|
||||||
Op: Operation<F, Req> + Send + Sync + Clone,
|
Op: Operation<F, Req> + Send + Sync + Clone,
|
||||||
Req: Debug,
|
Req: Debug,
|
||||||
Res: transformers::ToResponse<Req, PaymentData<F>, Op> + From<Req>,
|
Res: transformers::ToResponse<Req, PaymentData<F>, Op> + TryFrom<Req>,
|
||||||
// To create connector flow specific interface data
|
// To create connector flow specific interface data
|
||||||
PaymentData<F>: ConstructFlowSpecificData<F, FData, types::PaymentsResponseData>,
|
PaymentData<F>: ConstructFlowSpecificData<F, FData, types::PaymentsResponseData>,
|
||||||
types::RouterData<F, FData, types::PaymentsResponseData>: Feature<F, FData>,
|
types::RouterData<F, FData, types::PaymentsResponseData>: Feature<F, FData>,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use common_utils::ext_traits::AsyncExt;
|
use common_utils::ext_traits::{AsyncExt, Encode};
|
||||||
use error_stack::ResultExt;
|
use error_stack::ResultExt;
|
||||||
use router_derive::PaymentOperation;
|
use router_derive::PaymentOperation;
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
@ -143,7 +143,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
request,
|
request,
|
||||||
shipping_address.clone().map(|x| x.address_id),
|
shipping_address.clone().map(|x| x.address_id),
|
||||||
billing_address.clone().map(|x| x.address_id),
|
billing_address.clone().map(|x| x.address_id),
|
||||||
),
|
)?,
|
||||||
storage_scheme,
|
storage_scheme,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -481,14 +481,21 @@ impl PaymentCreate {
|
|||||||
request: &api::PaymentsRequest,
|
request: &api::PaymentsRequest,
|
||||||
shipping_address_id: Option<String>,
|
shipping_address_id: Option<String>,
|
||||||
billing_address_id: Option<String>,
|
billing_address_id: Option<String>,
|
||||||
) -> storage::PaymentIntentNew {
|
) -> RouterResult<storage::PaymentIntentNew> {
|
||||||
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
|
let created_at @ modified_at @ last_synced = Some(common_utils::date_time::now());
|
||||||
let status =
|
let status =
|
||||||
helpers::payment_intent_status_fsm(&request.payment_method_data, request.confirm);
|
helpers::payment_intent_status_fsm(&request.payment_method_data, request.confirm);
|
||||||
let client_secret =
|
let client_secret =
|
||||||
crate::utils::generate_id(consts::ID_LENGTH, format!("{payment_id}_secret").as_str());
|
crate::utils::generate_id(consts::ID_LENGTH, format!("{payment_id}_secret").as_str());
|
||||||
let (amount, currency) = (money.0, Some(money.1));
|
let (amount, currency) = (money.0, Some(money.1));
|
||||||
storage::PaymentIntentNew {
|
let metadata = request
|
||||||
|
.metadata
|
||||||
|
.as_ref()
|
||||||
|
.map(|a| Encode::<api_models::payments::Metadata>::encode_to_value(&a))
|
||||||
|
.transpose()
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Encoding Metadata to value failed")?;
|
||||||
|
Ok(storage::PaymentIntentNew {
|
||||||
payment_id: payment_id.to_string(),
|
payment_id: payment_id.to_string(),
|
||||||
merchant_id: merchant_id.to_string(),
|
merchant_id: merchant_id.to_string(),
|
||||||
status,
|
status,
|
||||||
@ -506,9 +513,9 @@ impl PaymentCreate {
|
|||||||
billing_address_id,
|
billing_address_id,
|
||||||
statement_descriptor_name: request.statement_descriptor_name.clone(),
|
statement_descriptor_name: request.statement_descriptor_name.clone(),
|
||||||
statement_descriptor_suffix: request.statement_descriptor_suffix.clone(),
|
statement_descriptor_suffix: request.statement_descriptor_suffix.clone(),
|
||||||
metadata: request.metadata.clone(),
|
metadata,
|
||||||
..storage::PaymentIntentNew::default()
|
..storage::PaymentIntentNew::default()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
|
|||||||
@ -103,7 +103,7 @@ where
|
|||||||
|
|
||||||
pub trait ToResponse<Req, D, Op>
|
pub trait ToResponse<Req, D, Op>
|
||||||
where
|
where
|
||||||
Self: From<Req>,
|
Self: TryFrom<Req>,
|
||||||
Op: Debug,
|
Op: Debug,
|
||||||
{
|
{
|
||||||
fn generate_response(
|
fn generate_response(
|
||||||
@ -118,7 +118,7 @@ where
|
|||||||
|
|
||||||
impl<F, Req, Op> ToResponse<Req, PaymentData<F>, Op> for api::PaymentsResponse
|
impl<F, Req, Op> ToResponse<Req, PaymentData<F>, Op> for api::PaymentsResponse
|
||||||
where
|
where
|
||||||
Self: From<Req>,
|
Self: TryFrom<Req>,
|
||||||
F: Clone,
|
F: Clone,
|
||||||
Op: Debug,
|
Op: Debug,
|
||||||
{
|
{
|
||||||
@ -233,7 +233,7 @@ pub fn payments_to_payments_response<R, Op>(
|
|||||||
operation: Op,
|
operation: Op,
|
||||||
) -> RouterResponse<api::PaymentsResponse>
|
) -> RouterResponse<api::PaymentsResponse>
|
||||||
where
|
where
|
||||||
api::PaymentsResponse: From<R>,
|
api::PaymentsResponse: TryFrom<R>,
|
||||||
Op: Debug,
|
Op: Debug,
|
||||||
{
|
{
|
||||||
let currency = payment_attempt
|
let currency = payment_attempt
|
||||||
@ -256,7 +256,9 @@ where
|
|||||||
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
|
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
|
||||||
services::BachResponse::Form(form)
|
services::BachResponse::Form(form)
|
||||||
} else {
|
} else {
|
||||||
let mut response: api::PaymentsResponse = request.into();
|
let mut response: api::PaymentsResponse = request
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
|
||||||
let mut next_action_response = None;
|
let mut next_action_response = None;
|
||||||
if payment_intent.status == enums::IntentStatus::RequiresCustomerAction {
|
if payment_intent.status == enums::IntentStatus::RequiresCustomerAction {
|
||||||
next_action_response = Some(api::NextAction {
|
next_action_response = Some(api::NextAction {
|
||||||
@ -406,7 +408,7 @@ impl<F: Clone> TryFrom<PaymentData<F>> for types::PaymentsAuthorizeData {
|
|||||||
.transpose()
|
.transpose()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let order_details = parsed_metadata.map(|data| data.order_details);
|
let order_details = parsed_metadata.and_then(|data| data.order_details);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
payment_method_data: {
|
payment_method_data: {
|
||||||
@ -504,7 +506,7 @@ impl<F: Clone> TryFrom<PaymentData<F>> for types::PaymentsSessionData {
|
|||||||
.transpose()
|
.transpose()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let order_details = parsed_metadata.map(|data| data.order_details);
|
let order_details = parsed_metadata.and_then(|data| data.order_details);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
amount: payment_data.amount.into(),
|
amount: payment_data.amount.into(),
|
||||||
|
|||||||
Reference in New Issue
Block a user