mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
fix(core): add ephemeral key to payment_create response when customer_id is mentioned (#1133)
This commit is contained in:
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -3000,7 +3000,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry"
|
name = "opentelemetry"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opentelemetry_api",
|
"opentelemetry_api",
|
||||||
"opentelemetry_sdk",
|
"opentelemetry_sdk",
|
||||||
@ -3009,7 +3009,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry-otlp"
|
name = "opentelemetry-otlp"
|
||||||
version = "0.11.0"
|
version = "0.11.0"
|
||||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"futures",
|
"futures",
|
||||||
@ -3026,7 +3026,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry-proto"
|
name = "opentelemetry-proto"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -3038,7 +3038,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry_api"
|
name = "opentelemetry_api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fnv",
|
"fnv",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
@ -3053,7 +3053,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry_sdk"
|
name = "opentelemetry_sdk"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://github.com/open-telemetry/opentelemetry-rust/?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
source = "git+https://github.com/open-telemetry/opentelemetry-rust?rev=44b90202fd744598db8b0ace5b8f0bad7ec45658#44b90202fd744598db8b0ace5b8f0bad7ec45658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
|||||||
14
crates/api_models/src/ephemeral_key.rs
Normal file
14
crates/api_models/src/ephemeral_key.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use serde;
|
||||||
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Eq, PartialEq, ToSchema)]
|
||||||
|
pub struct EphemeralKeyCreateResponse {
|
||||||
|
/// customer_id to which this ephemeral key belongs to
|
||||||
|
pub customer_id: String,
|
||||||
|
/// time at which this ephemeral key was created
|
||||||
|
pub created_at: i64,
|
||||||
|
/// time at which this ephemeral key would expire
|
||||||
|
pub expires: i64,
|
||||||
|
/// ephemeral key
|
||||||
|
pub secret: String,
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ pub mod cards_info;
|
|||||||
pub mod customers;
|
pub mod customers;
|
||||||
pub mod disputes;
|
pub mod disputes;
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
|
pub mod ephemeral_key;
|
||||||
#[cfg(feature = "errors")]
|
#[cfg(feature = "errors")]
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod files;
|
pub mod files;
|
||||||
|
|||||||
@ -7,7 +7,9 @@ use router_derive::Setter;
|
|||||||
use time::PrimitiveDateTime;
|
use time::PrimitiveDateTime;
|
||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
use crate::{admin, disputes, enums as api_enums, refunds};
|
use crate::{
|
||||||
|
admin, disputes, enums as api_enums, ephemeral_key::EphemeralKeyCreateResponse, refunds,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum PaymentOp {
|
pub enum PaymentOp {
|
||||||
@ -1190,6 +1192,9 @@ pub struct PaymentsResponse {
|
|||||||
/// Allowed Payment Method Types for a given PaymentIntent
|
/// Allowed Payment Method Types for a given PaymentIntent
|
||||||
#[schema(value_type = Option<Vec<PaymentMethodType>>)]
|
#[schema(value_type = Option<Vec<PaymentMethodType>>)]
|
||||||
pub allowed_payment_method_types: Option<Vec<api_enums::PaymentMethodType>>,
|
pub allowed_payment_method_types: Option<Vec<api_enums::PaymentMethodType>>,
|
||||||
|
|
||||||
|
/// ephemeral_key for the customer_id mentioned
|
||||||
|
pub ephemeral_key: Option<EphemeralKeyCreateResponse>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, ToSchema)]
|
#[derive(Clone, Debug, serde::Deserialize, ToSchema)]
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use error_stack::{IntoReport, ResultExt};
|
|||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use masking::Secret;
|
use masking::Secret;
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
|
use storage_models::ephemeral_key;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
pub use self::operations::{
|
pub use self::operations::{
|
||||||
@ -78,7 +79,6 @@ where
|
|||||||
.validate_request(&req, &merchant_account)?;
|
.validate_request(&req, &merchant_account)?;
|
||||||
|
|
||||||
tracing::Span::current().record("payment_id", &format!("{}", validate_result.payment_id));
|
tracing::Span::current().record("payment_id", &format!("{}", validate_result.payment_id));
|
||||||
|
|
||||||
let (operation, mut payment_data, customer_details) = operation
|
let (operation, mut payment_data, customer_details) = operation
|
||||||
.to_get_tracker()?
|
.to_get_tracker()?
|
||||||
.get_trackers(
|
.get_trackers(
|
||||||
@ -887,6 +887,7 @@ where
|
|||||||
pub creds_identifier: Option<String>,
|
pub creds_identifier: Option<String>,
|
||||||
pub pm_token: Option<String>,
|
pub pm_token: Option<String>,
|
||||||
pub connector_customer_id: Option<String>,
|
pub connector_customer_id: Option<String>,
|
||||||
|
pub ephemeral_key: Option<ephemeral_key::EphemeralKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|||||||
@ -151,6 +151,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
|
|||||||
@ -157,6 +157,7 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
|
|||||||
@ -194,6 +194,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
|
|||||||
creds_identifier: None,
|
creds_identifier: None,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(CustomerDetails {
|
Some(CustomerDetails {
|
||||||
customer_id: request.customer_id.clone(),
|
customer_id: request.customer_id.clone(),
|
||||||
|
|||||||
@ -228,6 +228,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(CustomerDetails {
|
Some(CustomerDetails {
|
||||||
customer_id: request.customer_id.clone(),
|
customer_id: request.customer_id.clone(),
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use common_utils::ext_traits::{AsyncExt, Encode, ValueExt};
|
|||||||
use error_stack::{self, ResultExt};
|
use error_stack::{self, ResultExt};
|
||||||
use router_derive::PaymentOperation;
|
use router_derive::PaymentOperation;
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
|
use storage_models::ephemeral_key;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, ValidateRequest};
|
use super::{BoxedOperation, Domain, GetTracker, Operation, UpdateTracker, ValidateRequest};
|
||||||
@ -17,6 +18,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
|
services,
|
||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, PaymentIdTypeExt},
|
||||||
@ -48,7 +50,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
Option<CustomerDetails>,
|
Option<CustomerDetails>,
|
||||||
)> {
|
)> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
|
let ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await;
|
||||||
let merchant_id = &merchant_account.merchant_id;
|
let merchant_id = &merchant_account.merchant_id;
|
||||||
let storage_scheme = merchant_account.storage_scheme;
|
let storage_scheme = merchant_account.storage_scheme;
|
||||||
|
|
||||||
@ -238,6 +240,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key,
|
||||||
},
|
},
|
||||||
Some(CustomerDetails {
|
Some(CustomerDetails {
|
||||||
customer_id: request.customer_id.clone(),
|
customer_id: request.customer_id.clone(),
|
||||||
@ -577,6 +580,31 @@ impl PaymentCreate {
|
|||||||
encoded_data: None,
|
encoded_data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip_all)]
|
||||||
|
pub async fn get_ephemeral_key(
|
||||||
|
request: &api::PaymentsRequest,
|
||||||
|
state: &AppState,
|
||||||
|
merchant_account: &storage::MerchantAccount,
|
||||||
|
) -> Option<ephemeral_key::EphemeralKey> {
|
||||||
|
match request.customer_id.clone() {
|
||||||
|
Some(customer_id) => helpers::make_ephemeral_key(
|
||||||
|
state,
|
||||||
|
customer_id,
|
||||||
|
merchant_account.merchant_id.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
.and_then(|ek| {
|
||||||
|
if let services::ApplicationResponse::Json(ek) = ek {
|
||||||
|
Some(ek)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
|
|||||||
@ -178,6 +178,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(payments::CustomerDetails {
|
Some(payments::CustomerDetails {
|
||||||
customer_id: request.customer_id.clone(),
|
customer_id: request.customer_id.clone(),
|
||||||
|
|||||||
@ -171,6 +171,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(customer_details),
|
Some(customer_details),
|
||||||
))
|
))
|
||||||
|
|||||||
@ -142,6 +142,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
|||||||
creds_identifier: None,
|
creds_identifier: None,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(customer_details),
|
Some(customer_details),
|
||||||
))
|
))
|
||||||
|
|||||||
@ -290,6 +290,7 @@ async fn get_tracker_for_sync<
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
))
|
))
|
||||||
|
|||||||
@ -294,6 +294,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
creds_identifier,
|
creds_identifier,
|
||||||
pm_token: None,
|
pm_token: None,
|
||||||
connector_customer_id: None,
|
connector_customer_id: None,
|
||||||
|
ephemeral_key: None,
|
||||||
},
|
},
|
||||||
Some(CustomerDetails {
|
Some(CustomerDetails {
|
||||||
customer_id: request.customer_id.clone(),
|
customer_id: request.customer_id.clone(),
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use std::{fmt::Debug, marker::PhantomData};
|
|||||||
use common_utils::fp_utils;
|
use common_utils::fp_utils;
|
||||||
use error_stack::{IntoReport, ResultExt};
|
use error_stack::{IntoReport, ResultExt};
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
|
use storage_models::ephemeral_key;
|
||||||
|
|
||||||
use super::{flows::Feature, PaymentAddress, PaymentData};
|
use super::{flows::Feature, PaymentAddress, PaymentData};
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -164,6 +165,7 @@ where
|
|||||||
server,
|
server,
|
||||||
payment_data.connector_response.authentication_data,
|
payment_data.connector_response.authentication_data,
|
||||||
operation,
|
operation,
|
||||||
|
payment_data.ephemeral_key,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,6 +256,7 @@ pub fn payments_to_payments_response<R, Op>(
|
|||||||
server: &Server,
|
server: &Server,
|
||||||
redirection_data: Option<serde_json::Value>,
|
redirection_data: Option<serde_json::Value>,
|
||||||
operation: Op,
|
operation: Op,
|
||||||
|
ephemeral_key_option: Option<ephemeral_key::EphemeralKey>,
|
||||||
) -> RouterResponse<api::PaymentsResponse>
|
) -> RouterResponse<api::PaymentsResponse>
|
||||||
where
|
where
|
||||||
Op: Debug,
|
Op: Debug,
|
||||||
@ -418,6 +421,7 @@ where
|
|||||||
parsed_metadata
|
parsed_metadata
|
||||||
.and_then(|metadata| metadata.allowed_payment_method_types),
|
.and_then(|metadata| metadata.allowed_payment_method_types),
|
||||||
)
|
)
|
||||||
|
.set_ephemeral_key(ephemeral_key_option.map(ForeignFrom::foreign_from))
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -489,6 +493,17 @@ impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::Pay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ForeignFrom<ephemeral_key::EphemeralKey> for api::ephemeral_key::EphemeralKeyCreateResponse {
|
||||||
|
fn foreign_from(from: ephemeral_key::EphemeralKey) -> Self {
|
||||||
|
Self {
|
||||||
|
customer_id: from.customer_id,
|
||||||
|
created_at: from.created_at,
|
||||||
|
expires: from.expires,
|
||||||
|
secret: from.secret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PaymentAdditionalData<'a, F>
|
pub struct PaymentAdditionalData<'a, F>
|
||||||
where
|
where
|
||||||
|
|||||||
@ -209,6 +209,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::mandates::MandateRevokedResponse,
|
api_models::mandates::MandateRevokedResponse,
|
||||||
api_models::mandates::MandateResponse,
|
api_models::mandates::MandateResponse,
|
||||||
api_models::mandates::MandateCardDetails,
|
api_models::mandates::MandateCardDetails,
|
||||||
|
api_models::ephemeral_key::EphemeralKeyCreateResponse,
|
||||||
crate::types::api::admin::MerchantAccountResponse,
|
crate::types::api::admin::MerchantAccountResponse,
|
||||||
crate::types::api::admin::MerchantConnectorId,
|
crate::types::api::admin::MerchantConnectorId,
|
||||||
crate::types::api::admin::MerchantDetails,
|
crate::types::api::admin::MerchantDetails,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ pub mod configs;
|
|||||||
pub mod customers;
|
pub mod customers;
|
||||||
pub mod disputes;
|
pub mod disputes;
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
|
pub mod ephemeral_key;
|
||||||
pub mod files;
|
pub mod files;
|
||||||
pub mod mandates;
|
pub mod mandates;
|
||||||
pub mod payment_methods;
|
pub mod payment_methods;
|
||||||
|
|||||||
1
crates/router/src/types/api/ephemeral_key.rs
Normal file
1
crates/router/src/types/api/ephemeral_key.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub use api_models::ephemeral_key::*;
|
||||||
@ -5,7 +5,7 @@ pub struct EphemeralKeyNew {
|
|||||||
pub secret: String,
|
pub secret: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct EphemeralKey {
|
pub struct EphemeralKey {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub merchant_id: String,
|
pub merchant_id: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user