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: add support for sdk session call in v2 #6502

Merged
merged 64 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
1e24930
refactor: introduce strict types in intent Domain and Diesel models
hrithikesh026 Oct 22, 2024
4be8ccb
add v1 and v2 feature flag to struct AuthenticationData
hrithikesh026 Oct 22, 2024
7aa6e95
address clippy lints
hrithikesh026 Oct 22, 2024
1d07bba
chore: run formatter
hyperswitch-bot[bot] Oct 22, 2024
560878b
feature_metadata field in payment intent to strict type
hrithikesh026 Oct 23, 2024
d7a2833
remove unwanted comments
hrithikesh026 Oct 23, 2024
a51df0d
remove secret
hrithikesh026 Oct 24, 2024
478d8bc
fix clippy lints
hrithikesh026 Oct 24, 2024
e3a5fc0
chore: update Cargo.lock
hyperswitch-bot[bot] Oct 24, 2024
0b84867
implement unimplemented todos
hrithikesh026 Oct 24, 2024
ffdf529
Merge branch 'main' into change-serde-value-to-strict-type-in-domain-…
hrithikesh026 Oct 25, 2024
59bbb16
use profile_id from jwt token
hrithikesh026 Oct 25, 2024
38ad685
avoid using OrderDetailsWithAmount from api models in router crate
hrithikesh026 Oct 25, 2024
ba16759
run +nightly fmt
hrithikesh026 Oct 25, 2024
1fbf051
Merge branch 'main' into change-serde-value-to-strict-type-in-domain-…
hrithikesh026 Oct 29, 2024
8c7ec98
address review comments
hrithikesh026 Oct 29, 2024
b364e22
use to_not_found_response instead of if else block
hrithikesh026 Oct 29, 2024
0ebac31
chore: add feature flags to Analytics route functions
hrithikesh026 Oct 30, 2024
82838f6
remove commented code
hrithikesh026 Oct 30, 2024
a55d468
address review comments
hrithikesh026 Oct 30, 2024
9737174
Merge branch 'main' into change-serde-value-to-strict-type-in-domain-…
hrithikesh026 Nov 4, 2024
be77504
address spell check errors
hrithikesh026 Nov 4, 2024
6645d06
fix cargo check errors
hrithikesh026 Nov 5, 2024
c02924f
fix: spell_check
hrithikesh026 Nov 5, 2024
734c7e0
Merge branch 'main' into change-serde-value-to-strict-type-in-domain-…
hrithikesh026 Nov 5, 2024
de69f4a
Merge branch 'main' into change-serde-value-to-strict-type-in-domain-…
hrithikesh026 Nov 6, 2024
bfd4a86
feat: add support for sdk session call in v2
hrithikesh026 Nov 7, 2024
191468e
chore: address v2 clippy warnings
hrithikesh026 Nov 7, 2024
6fcff7c
chore: use email from customer and remaove email from PaymentIntentData
hrithikesh026 Nov 7, 2024
6306242
chore: address v1 clippy warnings
hrithikesh026 Nov 7, 2024
d31c2c3
chore: remove client_secret from PaymentsSessionResponse
hrithikesh026 Nov 7, 2024
5bcb337
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Nov 7, 2024
ffab8e6
chore: remove update tracker and post update tracker implementation f…
hrithikesh026 Nov 7, 2024
0a78073
chore: remove MetadataUpdate variant
hrithikesh026 Nov 11, 2024
c6a3e9b
Merge remote-tracking branch 'origin/main' into add-support-for-sdk-s…
hrithikesh026 Nov 11, 2024
27681cc
chore: address comments
hrithikesh026 Nov 11, 2024
c9a5fdf
chore: fix cargo run failure
hrithikesh026 Nov 11, 2024
1753502
chore: add v2 flag to server function in payouts route
hrithikesh026 Nov 11, 2024
f44128f
address comments
hrithikesh026 Nov 11, 2024
41e5815
Merge remote-tracking branch 'origin/main' into add-support-for-sdk-s…
hrithikesh026 Nov 12, 2024
b15c16b
implement fn perform_routing for Session operation domain
hrithikesh026 Nov 12, 2024
9a0e85f
Merge remote-tracking branch 'origin/main' into add-support-for-sdk-s…
hrithikesh026 Nov 12, 2024
4ef98c8
chore: introduce GenericListWrapper
hrithikesh026 Nov 12, 2024
05e5345
chore: rename MerchantConnectorAccountList to MerchantConnectorAccounts
hrithikesh026 Nov 12, 2024
6496de2
chore: address cargo clippy lints
hrithikesh026 Nov 12, 2024
9c5aaa6
chore: introduce macro for generating list wrapper
hrithikesh026 Nov 12, 2024
23c46e6
chore: address v2 clippy lints
hrithikesh026 Nov 12, 2024
fa132de
Merge branch 'main' into add-support-for-sdk-session-v2
hrithikesh026 Nov 13, 2024
fe48a8b
Merge remote-tracking branch 'origin/main' into add-support-for-sdk-s…
hrithikesh026 Nov 14, 2024
64a6d1b
resolve merge conflicts
hrithikesh026 Nov 14, 2024
e984501
chore: add missing closing Braces
hrithikesh026 Nov 14, 2024
aeaeaf3
chore: implement ValidateStatusForOperation for PaymentSessionIntent
hrithikesh026 Nov 14, 2024
026a246
address comments
hrithikesh026 Nov 14, 2024
e8f0678
address comments
hrithikesh026 Nov 15, 2024
6c36a6b
address comments
hrithikesh026 Nov 15, 2024
3008ded
address comments
hrithikesh026 Nov 15, 2024
0c70b31
address clippy lints for v2
hrithikesh026 Nov 19, 2024
f24ddbf
address clippy lints for v2
hrithikesh026 Nov 20, 2024
86af92e
remove v1 feature flag
hrithikesh026 Nov 21, 2024
972fc00
only allow requires_payment_method status for payments session
hrithikesh026 Nov 21, 2024
c359eaa
Merge branch 'main' into add-support-for-sdk-session-v2
hrithikesh026 Nov 21, 2024
f2a7800
fix compilation error due to merge with main
hrithikesh026 Nov 27, 2024
3cd9f37
Merge remote-tracking branch 'origin/main' into add-support-for-sdk-s…
hrithikesh026 Nov 27, 2024
374f439
fix compilation error in v2 code
hrithikesh026 Nov 27, 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
5 changes: 0 additions & 5 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -15079,18 +15079,13 @@
"type": "object",
"required": [
"payment_id",
"client_secret",
"session_token"
],
"properties": {
"payment_id": {
"type": "string",
"description": "The identifier for the payment"
},
"client_secret": {
"type": "string",
"description": "This is a token which expires after 15 minutes, used from the client to authenticate and create sessions from the SDK"
},
"session_token": {
"type": "array",
"items": {
Expand Down
1 change: 0 additions & 1 deletion crates/api_models/src/events/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,6 @@ impl ApiEventMetric for PaymentsManualUpdateResponse {
}
}

#[cfg(feature = "v1")]
impl ApiEventMetric for PaymentsSessionResponse {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Payment {
Expand Down
11 changes: 11 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5988,6 +5988,7 @@ pub struct ApplepayErrorResponse {
pub status_message: String,
}

#[cfg(feature = "v1")]
#[derive(Default, Debug, serde::Serialize, Clone, ToSchema)]
pub struct PaymentsSessionResponse {
/// The identifier for the payment
Expand All @@ -6000,6 +6001,16 @@ pub struct PaymentsSessionResponse {
pub session_token: Vec<SessionToken>,
}

#[cfg(feature = "v2")]
#[derive(Debug, serde::Serialize, Clone, ToSchema)]
pub struct PaymentsSessionResponse {
/// The identifier for the payment
#[schema(value_type = String)]
pub payment_id: id_type::GlobalPaymentId,
/// The list of session token object
pub session_token: Vec<SessionToken>,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
pub struct PaymentRetrieveBody {
/// The identifier for the Merchant Account.
Expand Down
35 changes: 35 additions & 0 deletions crates/common_utils/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,41 @@ mod id_type {
}
}

/// Create new generic list wrapper
#[macro_export]
macro_rules! create_list_wrapper {
(
$wrapper_name:ident,
$type_name: ty,
impl_functions: {
$($function_def: tt)*
}
) => {
pub struct $wrapper_name(Vec<$type_name>);
impl $wrapper_name {
pub fn new(list: Vec<$type_name>) -> Self {
Self(list)
}
pub fn iter(&self) -> std::slice::Iter<'_, $type_name> {
self.0.iter()
}
$($function_def)*
}
impl Iterator for $wrapper_name {
type Item = $type_name;
fn next(&mut self) -> Option<Self::Item> {
self.0.pop()
}
}

impl FromIterator<$type_name> for $wrapper_name {
fn from_iter<T: IntoIterator<Item = $type_name>>(iter: T) -> Self {
Self(iter.into_iter().collect())
}
}
};
}

/// Get the type name for a type
#[macro_export]
macro_rules! type_name {
Expand Down
2 changes: 1 addition & 1 deletion crates/common_utils/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ mod client_secret_type {
Ok(row)
}
}

crate::impl_serializable_secret_id_type!(ClientSecret);
#[cfg(test)]
mod client_secret_tests {
#![allow(clippy::expect_used)]
Expand Down
124 changes: 98 additions & 26 deletions crates/hyperswitch_domain_models/src/merchant_connector_account.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#[cfg(feature = "v2")]
use api_models::admin;
#[cfg(feature = "v2")]
use common_utils::ext_traits::ValueExt;
use common_utils::{
crypto::Encryptable,
date_time,
Expand All @@ -9,11 +13,15 @@ use common_utils::{
use diesel_models::{enums, merchant_connector_account::MerchantConnectorAccountUpdateInternal};
use error_stack::ResultExt;
use masking::{PeekInterface, Secret};
#[cfg(feature = "v2")]
use router_env::logger;
use rustc_hash::FxHashMap;
use serde_json::Value;

use super::behaviour;
#[cfg(feature = "v2")]
use crate::errors::api_error_response::ApiErrorResponse;
#[cfg(feature = "v2")]
use crate::router_data;
use crate::type_encryption::{crypto_operation, CryptoOperation};

Expand Down Expand Up @@ -90,6 +98,27 @@ impl MerchantConnectorAccount {
self.id.clone()
}

pub fn get_metadata(&self) -> Option<pii::SecretSerdeValue> {
self.metadata.clone()
}

pub fn get_parsed_payment_methods_enabled(
&self,
) -> Vec<CustomResult<admin::PaymentMethodsEnabled, ApiErrorResponse>> {
self.payment_methods_enabled
.clone()
.unwrap_or_default()
.into_iter()
.map(|payment_methods_enabled| {
payment_methods_enabled
.parse_value::<admin::PaymentMethodsEnabled>("payment_methods_enabled")
.change_context(ApiErrorResponse::InvalidDataValue {
field_name: "payment_methods_enabled",
})
})
.collect()
}

pub fn is_disabled(&self) -> bool {
self.disabled.unwrap_or(false)
}
Expand Down Expand Up @@ -530,31 +559,74 @@ impl From<MerchantConnectorAccountUpdate> for MerchantConnectorAccountUpdateInte
}
}

#[derive(Debug)]
pub struct MerchantConnectorAccounts(Vec<MerchantConnectorAccount>);

impl MerchantConnectorAccounts {
pub fn new(merchant_connector_accounts: Vec<MerchantConnectorAccount>) -> Self {
Self(merchant_connector_accounts)
}

pub fn is_merchant_connector_account_id_in_connector_mandate_details(
&self,
profile_id: Option<&id_type::ProfileId>,
connector_mandate_details: &diesel_models::PaymentsMandateReference,
) -> bool {
let mca_ids = self
.0
.iter()
.filter(|mca| {
mca.disabled.is_some_and(|disabled| !disabled)
&& profile_id.is_some_and(|profile_id| *profile_id == mca.profile_id)
})
.map(|mca| mca.get_id())
.collect::<std::collections::HashSet<_>>();
common_utils::create_list_wrapper!(
MerchantConnectorAccounts,
MerchantConnectorAccount,
impl_functions: {
#[cfg(feature = "v2")]
pub fn get_connector_and_supporting_payment_method_type_for_session_call(
&self,
) -> Vec<(&MerchantConnectorAccount, common_enums::PaymentMethodType)> {
let mut connector_and_supporting_payment_method_type = Vec::new();
hrithikesh026 marked this conversation as resolved.
Show resolved Hide resolved
self.iter().for_each(|connector_account| {
let res = connector_account
.get_parsed_payment_methods_enabled()
hrithikesh026 marked this conversation as resolved.
Show resolved Hide resolved
.into_iter()
.filter_map(|parsed_payment_method_result| {
parsed_payment_method_result
.inspect_err(|err| {
logger::error!(session_token_parsing_error=?err);
})
.ok()
})
.flat_map(|parsed_payment_methods_enabled| {
parsed_payment_methods_enabled
.payment_method_types
.unwrap_or_default()
.into_iter()
.filter(|payment_method_type| {
let is_invoke_sdk_client = matches!(
payment_method_type.payment_experience,
Some(api_models::enums::PaymentExperience::InvokeSdkClient)
);
is_invoke_sdk_client
})
.map(|payment_method_type| {
(connector_account, payment_method_type.payment_method_type)
})
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
connector_and_supporting_payment_method_type.extend(res);
});
connector_and_supporting_payment_method_type
}
pub fn filter_based_on_profile_and_connector_type(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have this filter on the query itself? cc: @jarnura

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will take this up in a new PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can filter on the query, since these are domain models and the function present in domain model crate

self,
profile_id: &id_type::ProfileId,
connector_type: common_enums::ConnectorType,
) -> Self {
self.into_iter()
.filter(|mca| &mca.profile_id == profile_id && mca.connector_type == connector_type)
.collect()
}
pub fn is_merchant_connector_account_id_in_connector_mandate_details(
&self,
profile_id: Option<&id_type::ProfileId>,
connector_mandate_details: &diesel_models::PaymentsMandateReference,
) -> bool {
let mca_ids = self
.iter()
.filter(|mca| {
mca.disabled.is_some_and(|disabled| !disabled)
&& profile_id.is_some_and(|profile_id| *profile_id == mca.profile_id)
})
.map(|mca| mca.get_id())
.collect::<std::collections::HashSet<_>>();

connector_mandate_details
.keys()
.any(|mca_id| mca_ids.contains(mca_id))
connector_mandate_details
.keys()
.any(|mca_id| mca_ids.contains(mca_id))
}
}
}
);
3 changes: 2 additions & 1 deletion crates/hyperswitch_domain_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::marker::PhantomData;

#[cfg(feature = "v2")]
use api_models::payments::Address;
use api_models::payments::{Address, SessionToken};
use common_utils::{
self,
crypto::Encryptable,
Expand Down Expand Up @@ -527,6 +527,7 @@ where
{
pub flow: PhantomData<F>,
pub payment_intent: PaymentIntent,
pub sessions_token: Vec<SessionToken>,
}

// TODO: Check if this can be merged with existing payment data
Expand Down
4 changes: 2 additions & 2 deletions crates/router/src/analytics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ pub mod routes {

impl Analytics {
#[cfg(feature = "v2")]
pub fn server(_state: AppState) -> Scope {
todo!()
pub fn server(state: AppState) -> Scope {
web::scope("/analytics").app_data(web::Data::new(state))
}
#[cfg(feature = "v1")]
pub fn server(state: AppState) -> Scope {
Expand Down
Loading
Loading