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(payment_methods_v2): Added Ephemeral auth for v2 #6813

Merged
merged 30 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
77b6c06
feat(v2): Add ephemeral auth for v2
Sarthak1799 Dec 11, 2024
4927db3
refactor: Refactored pm v2 code
Sarthak1799 Dec 11, 2024
8078355
chore: run formatter
hyperswitch-bot[bot] Dec 11, 2024
7d0a4db
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Dec 11, 2024
423c713
fix: Fixed error responses and eph endpoint
Sarthak1799 Dec 11, 2024
241921c
fix: Added checks on pm retrieve
Sarthak1799 Dec 11, 2024
f8d6dd9
fix: Fixed errors
Sarthak1799 Dec 12, 2024
b0e1365
chore: Resolved comments
Sarthak1799 Dec 12, 2024
cf0c5f8
chore: Resolved comments
Sarthak1799 Dec 16, 2024
631a628
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Dec 16, 2024
8206b9c
refactor: Refcatored to use publishible_key auth as well
Sarthak1799 Dec 16, 2024
ba456d6
Merge branch 'main' of github.com:juspay/hyperswitch into ephemeral-a…
Sarthak1799 Dec 17, 2024
07fd9d8
chore: run formatter
hyperswitch-bot[bot] Dec 17, 2024
dfe8d54
fix: Fixed errors
Sarthak1799 Dec 17, 2024
d4bd82c
refactor: Refactored to use GlobalCustomerId
Sarthak1799 Dec 18, 2024
455b89f
chore: run formatter
hyperswitch-bot[bot] Dec 18, 2024
3cbce21
fix: Fixed clippy errors
Sarthak1799 Dec 18, 2024
295753d
chore: run formatter
hyperswitch-bot[bot] Dec 18, 2024
bd232c7
chore: Resolved comments
Sarthak1799 Dec 18, 2024
a809655
fix: Fixed errors
Sarthak1799 Dec 18, 2024
7aa4143
chore: Resolved comments
Sarthak1799 Dec 18, 2024
35cd0b4
chore: Resolved comments
Sarthak1799 Dec 19, 2024
c705733
chore: run formatter
hyperswitch-bot[bot] Dec 19, 2024
81f6888
chore: Resolved comments
Sarthak1799 Dec 19, 2024
a7b3b6e
fix: Fixed errors
Sarthak1799 Dec 19, 2024
d1c4b9b
fix: Fixed errors
Sarthak1799 Dec 19, 2024
cc2c594
chore: Resolved comments
Sarthak1799 Dec 19, 2024
d4cbc53
chore: Resolved comments
Sarthak1799 Dec 19, 2024
e980125
chore: Resolved comments
Sarthak1799 Dec 19, 2024
967d9f9
fix: Fixed errors
Sarthak1799 Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -13696,16 +13696,11 @@
"PaymentMethodIntentConfirm": {
"type": "object",
"required": [
"client_secret",
"payment_method_data",
"payment_method_type",
"payment_method_subtype"
],
"properties": {
"client_secret": {
"type": "string",
"description": "For SDK based calls, client_secret would be required"
},
"customer_id": {
"type": "string",
"description": "The unique identifier of the customer.",
Expand Down Expand Up @@ -13991,7 +13986,7 @@
"example": "2024-02-24T11:04:09.922Z",
"nullable": true
},
"client_secret": {
"ephemeral_key": {
"type": "string",
"description": "For Client based calls",
"nullable": true
Expand Down Expand Up @@ -14140,14 +14135,6 @@
"properties": {
"payment_method_data": {
"$ref": "#/components/schemas/PaymentMethodUpdateData"
},
"client_secret": {
"type": "string",
"description": "This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK",
"example": "secret_k2uj3he2893eiu2d",
"nullable": true,
"maxLength": 30,
"minLength": 30
}
},
"additionalProperties": false
Expand Down
43 changes: 43 additions & 0 deletions crates/api_models/src/ephemeral_key.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use common_utils::id_type;
#[cfg(feature = "v2")]
use masking::Secret;
use serde;
use utoipa::ToSchema;

#[cfg(feature = "v1")]
/// Information required to create an ephemeral key.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct EphemeralKeyCreateRequest {
Expand All @@ -15,12 +18,52 @@ pub struct EphemeralKeyCreateRequest {
pub customer_id: id_type::CustomerId,
}

#[cfg(feature = "v2")]
/// Information required to create an ephemeral key.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct EphemeralKeyCreateRequest {
/// Customer ID for which an ephemeral key must be created
#[schema(
min_length = 32,
max_length = 64,
value_type = String,
example = "12345_cus_01926c58bc6e77c09e809964e72af8c8"
)]
pub customer_id: id_type::GlobalCustomerId,
}

#[cfg(feature = "v2")]
/// ephemeral_key for the customer_id mentioned
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Eq, PartialEq, ToSchema)]
pub struct EphemeralKeyResponse {
/// Ephemeral key id
#[schema(value_type = String, max_length = 32, min_length = 1)]
pub id: id_type::EphemeralKeyId,
/// customer_id to which this ephemeral key belongs to
#[schema(value_type = String, max_length = 64, min_length = 32, example = "12345_cus_01926c58bc6e77c09e809964e72af8c8")]
pub customer_id: id_type::GlobalCustomerId,
/// time at which this ephemeral key was created
pub created_at: time::PrimitiveDateTime,
/// time at which this ephemeral key would expire
pub expires: time::PrimitiveDateTime,
#[schema(value_type=String)]
/// ephemeral key
pub secret: Secret<String>,
}

impl common_utils::events::ApiEventMetric for EphemeralKeyCreateRequest {
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
Some(common_utils::events::ApiEventsType::Miscellaneous)
}
}

#[cfg(feature = "v2")]
impl common_utils::events::ApiEventMetric for EphemeralKeyResponse {
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
Some(common_utils::events::ApiEventsType::Miscellaneous)
}
}

/// ephemeral_key for the customer_id mentioned
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Eq, PartialEq, ToSchema)]
pub struct EphemeralKeyCreateResponse {
Expand Down
14 changes: 2 additions & 12 deletions crates/api_models/src/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,6 @@ pub struct PaymentMethodIntentCreate {
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[serde(deny_unknown_fields)]
pub struct PaymentMethodIntentConfirm {
/// For SDK based calls, client_secret would be required
pub client_secret: String,

/// The unique identifier of the customer.
#[schema(value_type = Option<String>, max_length = 64, min_length = 1, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")]
pub customer_id: Option<id_type::CustomerId>,
Expand Down Expand Up @@ -211,9 +208,6 @@ pub struct PaymentMethodIntentConfirmInternal {
#[schema(value_type = PaymentMethodType,example = "credit")]
pub payment_method_subtype: api_enums::PaymentMethodType,

/// For SDK based calls, client_secret would be required
pub client_secret: String,

/// The unique identifier of the customer.
#[schema(value_type = Option<String>, max_length = 64, min_length = 1, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")]
pub customer_id: Option<id_type::CustomerId>,
Expand All @@ -226,7 +220,6 @@ pub struct PaymentMethodIntentConfirmInternal {
impl From<PaymentMethodIntentConfirmInternal> for PaymentMethodIntentConfirm {
fn from(item: PaymentMethodIntentConfirmInternal) -> Self {
Self {
client_secret: item.client_secret,
payment_method_type: item.payment_method_type,
payment_method_subtype: item.payment_method_subtype,
customer_id: item.customer_id,
Expand Down Expand Up @@ -408,10 +401,6 @@ pub struct PaymentMethodUpdate {
pub struct PaymentMethodUpdate {
/// payment method data to be passed
pub payment_method_data: PaymentMethodUpdateData,

/// This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK
#[schema(max_length = 30, min_length = 30, example = "secret_k2uj3he2893eiu2d")]
pub client_secret: Option<String>,
}

#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
Expand Down Expand Up @@ -826,7 +815,8 @@ pub struct PaymentMethodResponse {
pub last_used_at: Option<time::PrimitiveDateTime>,

/// For Client based calls
pub client_secret: Option<String>,
#[schema(value_type=Option<String>)]
pub ephemeral_key: Option<masking::Secret<String>>,

pub payment_method_data: Option<PaymentMethodResponseData>,
}
Expand Down
3 changes: 3 additions & 0 deletions crates/common_utils/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ pub enum ApiEventsType {
poll_id: String,
},
Analytics,
EphemeralKey {
key_id: id_type::EphemeralKeyId,
},
}

impl ApiEventMetric for serde_json::Value {}
Expand Down
2 changes: 2 additions & 0 deletions crates/common_utils/src/id_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

mod api_key;
mod customer;
mod ephemeral_key;
#[cfg(feature = "v2")]
mod global_id;
mod merchant;
Expand Down Expand Up @@ -37,6 +38,7 @@ pub use self::global_id::{
pub use self::{
api_key::ApiKeyId,
customer::CustomerId,
ephemeral_key::EphemeralKeyId,
merchant::MerchantId,
merchant_connector_account::MerchantConnectorAccountId,
organization::OrganizationId,
Expand Down
31 changes: 31 additions & 0 deletions crates/common_utils/src/id_type/ephemeral_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
crate::id_type!(
EphemeralKeyId,
"A type for key_id that can be used for Ephemeral key IDs"
);
crate::impl_id_type_methods!(EphemeralKeyId, "key_id");

// This is to display the `EphemeralKeyId` as EphemeralKeyId(abcd)
crate::impl_debug_id_type!(EphemeralKeyId);
crate::impl_try_from_cow_str_id_type!(EphemeralKeyId, "key_id");

crate::impl_generate_id_id_type!(EphemeralKeyId, "eki");
crate::impl_serializable_secret_id_type!(EphemeralKeyId);
crate::impl_queryable_id_type!(EphemeralKeyId);
crate::impl_to_sql_from_sql_id_type!(EphemeralKeyId);

impl crate::events::ApiEventMetric for EphemeralKeyId {
fn get_api_event_type(&self) -> Option<crate::events::ApiEventsType> {
Some(crate::events::ApiEventsType::EphemeralKey {
key_id: self.clone(),
})
}
}

crate::impl_default_id_type!(EphemeralKeyId, "key");

impl EphemeralKeyId {
/// Generate a key for redis
pub fn generate_redis_key(&self) -> String {
format!("epkey_{}", self.get_string_repr())
}
}
48 changes: 48 additions & 0 deletions crates/diesel_models/src/ephemeral_key.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
#[cfg(feature = "v2")]
use masking::{PeekInterface, Secret};
#[cfg(feature = "v2")]
pub struct EphemeralKeyTypeNew {
pub id: common_utils::id_type::EphemeralKeyId,
pub merchant_id: common_utils::id_type::MerchantId,
pub customer_id: common_utils::id_type::GlobalCustomerId,
pub secret: Secret<String>,
pub resource_type: ResourceType,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct EphemeralKeyType {
pub id: common_utils::id_type::EphemeralKeyId,
pub merchant_id: common_utils::id_type::MerchantId,
pub customer_id: common_utils::id_type::GlobalCustomerId,
pub resource_type: ResourceType,
pub created_at: time::PrimitiveDateTime,
pub expires: time::PrimitiveDateTime,
pub secret: Secret<String>,
}

#[cfg(feature = "v2")]
impl EphemeralKeyType {
pub fn generate_secret_key(&self) -> String {
format!("epkey_{}", self.secret.peek())
}
}

pub struct EphemeralKeyNew {
pub id: String,
pub merchant_id: common_utils::id_type::MerchantId,
Expand All @@ -20,3 +50,21 @@ impl common_utils::events::ApiEventMetric for EphemeralKey {
Some(common_utils::events::ApiEventsType::Miscellaneous)
}
}

#[derive(
Clone,
Copy,
Debug,
serde::Serialize,
serde::Deserialize,
strum::Display,
strum::EnumString,
PartialEq,
Eq,
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum ResourceType {
Payment,
PaymentMethod,
}
13 changes: 12 additions & 1 deletion crates/diesel_models/src/payment_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ pub enum PaymentMethodUpdate {
network_token_requestor_reference_id: Option<String>,
network_token_locker_id: Option<String>,
network_token_payment_method_data: Option<Encryption>,
locker_fingerprint_id: Option<String>,
},
ConnectorMandateDetailsUpdate {
connector_mandate_details: Option<PaymentsMandateReference>,
Expand Down Expand Up @@ -322,6 +323,7 @@ pub struct PaymentMethodUpdateInternal {
network_token_requestor_reference_id: Option<String>,
network_token_locker_id: Option<String>,
network_token_payment_method_data: Option<Encryption>,
locker_fingerprint_id: Option<String>,
}

#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
Expand All @@ -341,6 +343,7 @@ impl PaymentMethodUpdateInternal {
network_token_requestor_reference_id,
network_token_locker_id,
network_token_payment_method_data,
locker_fingerprint_id,
} = self;

PaymentMethod {
Expand All @@ -359,7 +362,7 @@ impl PaymentMethodUpdateInternal {
client_secret: source.client_secret,
payment_method_billing_address: source.payment_method_billing_address,
updated_by: updated_by.or(source.updated_by),
locker_fingerprint_id: source.locker_fingerprint_id,
locker_fingerprint_id: locker_fingerprint_id.or(source.locker_fingerprint_id),
payment_method_type_v2: payment_method_type_v2.or(source.payment_method_type_v2),
payment_method_subtype: payment_method_subtype.or(source.payment_method_subtype),
id: source.id,
Expand Down Expand Up @@ -695,6 +698,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
PaymentMethodUpdate::LastUsedUpdate { last_used_at } => Self {
payment_method_data: None,
Expand All @@ -710,6 +714,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
PaymentMethodUpdate::UpdatePaymentMethodDataAndLastUsed {
payment_method_data,
Expand All @@ -728,6 +733,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
PaymentMethodUpdate::NetworkTransactionIdAndStatusUpdate {
network_transaction_id,
Expand All @@ -746,6 +752,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
PaymentMethodUpdate::StatusUpdate { status } => Self {
payment_method_data: None,
Expand All @@ -761,6 +768,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
PaymentMethodUpdate::AdditionalDataUpdate {
payment_method_data,
Expand All @@ -771,6 +779,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_requestor_reference_id,
network_token_locker_id,
network_token_payment_method_data,
locker_fingerprint_id,
} => Self {
payment_method_data,
last_used_at: None,
Expand All @@ -785,6 +794,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_requestor_reference_id,
network_token_locker_id,
network_token_payment_method_data,
locker_fingerprint_id,
},
PaymentMethodUpdate::ConnectorMandateDetailsUpdate {
connector_mandate_details,
Expand All @@ -802,6 +812,7 @@ impl From<PaymentMethodUpdate> for PaymentMethodUpdateInternal {
network_token_locker_id: None,
network_token_requestor_reference_id: None,
network_token_payment_method_data: None,
locker_fingerprint_id: None,
},
}
}
Expand Down
5 changes: 4 additions & 1 deletion crates/hyperswitch_domain_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ pub mod payment_intent;

use common_enums as storage_enums;
#[cfg(feature = "v2")]
use diesel_models::types::{FeatureMetadata, OrderDetailsWithAmount};
use diesel_models::{
ephemeral_key,
types::{FeatureMetadata, OrderDetailsWithAmount},
};

use self::payment_attempt::PaymentAttempt;
#[cfg(feature = "v1")]
Expand Down
Loading
Loading