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(router): add an api to migrate the apple pay certificates from connector metadata to connector_wallets_details column in merchant connector account #4790

Merged
merged 40 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1d41ab0
add column certificates in the merchant connector account
ShankarSinghC May 27, 2024
5957ad2
remove column certificates in the merchant connector account
ShankarSinghC May 28, 2024
582ee22
feat(router): add an api to migrate the apple pay certificates from c…
ShankarSinghC May 28, 2024
40fb53f
fix openapi error
ShankarSinghC May 28, 2024
60c4281
add connector_wallets_details in mca retrieve
ShankarSinghC May 28, 2024
9a47f30
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] May 28, 2024
24c6a7d
Merge branch 'main' of https://github.com/juspay/hyperswitch into app…
ShankarSinghC May 28, 2024
47ef629
if create mca has apple pay details in the metadata insert it in the …
ShankarSinghC May 28, 2024
c1995c4
add connector_wallets_details in router data
ShankarSinghC May 29, 2024
290a854
Merge branch 'apple_pay/migrate-cert' of https://github.com/juspay/hy…
ShankarSinghC May 29, 2024
4689a4a
add connector_wallets_details fallback for mca create
ShankarSinghC May 29, 2024
7b9fcfc
remove connector_wallets_details from mca request
ShankarSinghC May 29, 2024
a9700b3
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] May 29, 2024
f1e046e
add a ppc, ppc_key, ppc_at fields in apple pay session token
ShankarSinghC May 30, 2024
855b567
Merge branch 'apple_pay/migrate-cert' of https://github.com/juspay/hy…
ShankarSinghC May 30, 2024
200d2d5
generate openeapi spec
ShankarSinghC May 30, 2024
b86f448
remove connector_wallets_details from mca update request
ShankarSinghC May 30, 2024
9299f81
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] May 30, 2024
2f62932
Merge branch 'main' of https://github.com/juspay/hyperswitch into app…
ShankarSinghC May 30, 2024
822e2aa
Merge branch 'apple_pay/migrate-cert' of https://github.com/juspay/hy…
ShankarSinghC May 30, 2024
09e9dd3
address pr comments
ShankarSinghC May 30, 2024
9658e95
Merge branch 'main' into apple_pay/migrate-cert
ShankarSinghC May 30, 2024
13ec3a2
address pr comments
ShankarSinghC Jun 1, 2024
7321758
Merge branch 'main' of https://github.com/juspay/hyperswitch into app…
ShankarSinghC Jun 1, 2024
0767c55
fix typos
ShankarSinghC Jun 1, 2024
72309c8
accept list of merchant ids as input to the certificate migration api
ShankarSinghC Jun 2, 2024
ca7936d
fix typos
ShankarSinghC Jun 2, 2024
32b7859
remove the unnecessary import
ShankarSinghC Jun 2, 2024
58e44a0
make fields ApplePayCertificatesMigrationResponse as sanke case
ShankarSinghC Jun 2, 2024
fd5aa68
fix clippy errors
ShankarSinghC Jun 2, 2024
93dc945
make connector_wallets_details field in ConnectorWalletDetailsUpdate …
ShankarSinghC Jun 3, 2024
daad5ba
address pr comments
ShankarSinghC Jun 3, 2024
3d27be8
Merge branch 'main' of https://github.com/juspay/hyperswitch into app…
ShankarSinghC Jun 3, 2024
15df915
chore: run formatter
hyperswitch-bot[bot] Jun 3, 2024
a3ca704
Replace AppState with SessionState
ShankarSinghC Jun 4, 2024
acd2eea
retrun the underlying error in the generics
ShankarSinghC Jun 5, 2024
8a58000
impl db transaction to update multiple merchant connector accounts
ShankarSinghC Jun 5, 2024
16c15d7
fix clippy errors
ShankarSinghC Jun 5, 2024
4aa32f6
address pr comments
ShankarSinghC Jun 5, 2024
4ab8a62
Update crates/router/src/core/apple_pay_certificates_migration.rs
ShankarSinghC Jun 5, 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
12 changes: 12 additions & 0 deletions crates/api_models/src/apple_pay_certificates_migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#[derive(Debug, Clone, serde::Serialize)]
pub struct ApplePayCertificatesMigrationResponse {
pub migration_successful: Vec<String>,
pub migration_failed: Vec<String>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct ApplePayCertificatesMigrationRequest {
pub merchant_ids: Vec<String>,
}

impl common_utils::events::ApiEventMetric for ApplePayCertificatesMigrationRequest {}
1 change: 1 addition & 0 deletions crates/api_models/src/events.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod apple_pay_certificates_migration;
pub mod connector_onboarding;
pub mod customer;
pub mod dispute;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use common_utils::events::ApiEventMetric;

use crate::apple_pay_certificates_migration::ApplePayCertificatesMigrationResponse;

impl ApiEventMetric for ApplePayCertificatesMigrationResponse {
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
Some(common_utils::events::ApiEventsType::ApplePayCertificatesMigration)
}
}
1 change: 1 addition & 0 deletions crates/api_models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pub mod admin;
pub mod analytics;
pub mod api_keys;
pub mod apple_pay_certificates_migration;
pub mod blocklist;
pub mod cards_info;
pub mod conditional_configs;
Expand Down
17 changes: 17 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4208,6 +4208,23 @@ pub struct SessionTokenInfo {
pub initiative_context: String,
#[schema(value_type = Option<CountryAlpha2>)]
pub merchant_business_country: Option<api_enums::CountryAlpha2>,
#[serde(flatten)]
pub payment_processing_details_at: Option<PaymentProcessingDetailsAt>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
#[serde(tag = "payment_processing_details_at")]
pub enum PaymentProcessingDetailsAt {
Hyperswitch(PaymentProcessingDetails),
Connector,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, ToSchema)]
pub struct PaymentProcessingDetails {
#[schema(value_type = String)]
pub payment_processing_certificate: Secret<String>,
#[schema(value_type = String)]
pub payment_processing_certificate_key: Secret<String>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
Expand Down
5 changes: 0 additions & 5 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2284,11 +2284,6 @@ pub enum ReconStatus {
Active,
Disabled,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ApplePayFlow {
Simplified,
Manual,
}

#[derive(
Clone,
Expand Down
1 change: 1 addition & 0 deletions crates/common_utils/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub enum ApiEventsType {
// TODO: This has to be removed once the corresponding apiEventTypes are created
Miscellaneous,
RustLocker,
ApplePayCertificatesMigration,
FraudCheck,
Recon,
Dispute {
Expand Down
2 changes: 1 addition & 1 deletion crates/connector_configs/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub enum ConnectorAuthType {
#[derive(Debug, Deserialize, serde::Serialize, Clone)]
#[serde(untagged)]
pub enum ApplePayTomlConfig {
Standard(payments::ApplePayMetadata),
Standard(Box<payments::ApplePayMetadata>),
Zen(ZenApplePay),
}

Expand Down
3 changes: 3 additions & 0 deletions crates/diesel_models/src/merchant_connector_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub struct MerchantConnectorAccount {
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: storage_enums::ConnectorStatus,
pub connector_wallets_details: Option<Encryption>,
}

#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
Expand Down Expand Up @@ -72,6 +73,7 @@ pub struct MerchantConnectorAccountNew {
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: storage_enums::ConnectorStatus,
pub connector_wallets_details: Option<Encryption>,
}

#[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)]
Expand All @@ -96,6 +98,7 @@ pub struct MerchantConnectorAccountUpdateInternal {
pub applepay_verified_domains: Option<Vec<String>>,
pub pm_auth_config: Option<serde_json::Value>,
pub status: Option<storage_enums::ConnectorStatus>,
pub connector_wallets_details: Option<Encryption>,
}

impl MerchantConnectorAccountUpdateInternal {
Expand Down
6 changes: 4 additions & 2 deletions crates/diesel_models/src/query/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ where
}
Err(DieselError::NotFound) => Err(report!(errors::DatabaseError::NotFound))
.attach_printable_lazy(|| format!("Error while updating {debug_values}")),
_ => Err(report!(errors::DatabaseError::Others))
Err(error) => Err(error)
.change_context(errors::DatabaseError::Others)
.attach_printable_lazy(|| format!("Error while updating {debug_values}")),
}
}
Expand Down Expand Up @@ -252,7 +253,8 @@ where
}
Err(DieselError::NotFound) => Err(report!(errors::DatabaseError::NotFound))
.attach_printable_lazy(|| format!("Error while updating by ID {debug_values}")),
_ => Err(report!(errors::DatabaseError::Others))
Err(error) => Err(error)
.change_context(errors::DatabaseError::Others)
.attach_printable_lazy(|| format!("Error while updating by ID {debug_values}")),
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/diesel_models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,7 @@ diesel::table! {
applepay_verified_domains -> Nullable<Array<Nullable<Text>>>,
pm_auth_config -> Nullable<Jsonb>,
status -> ConnectorStatus,
connector_wallets_details -> Nullable<Bytea>,
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/hyperswitch_domain_models/src/payment_method_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ pub enum PaymentMethodData {
CardToken(CardToken),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ApplePayFlow {
Simplified(api_models::payments::PaymentProcessingDetails),
Manual,
}

impl PaymentMethodData {
pub fn get_payment_method(&self) -> Option<common_enums::PaymentMethod> {
match self {
Expand Down
5 changes: 3 additions & 2 deletions crates/hyperswitch_domain_models/src/router_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, marker::PhantomData};
use common_utils::id_type;
use masking::Secret;

use crate::payment_address::PaymentAddress;
use crate::{payment_address::PaymentAddress, payment_method_data};

#[derive(Debug, Clone)]
pub struct RouterData<Flow, Request, Response> {
Expand All @@ -22,6 +22,7 @@ pub struct RouterData<Flow, Request, Response> {
pub address: PaymentAddress,
pub auth_type: common_enums::enums::AuthenticationType,
pub connector_meta_data: Option<common_utils::pii::SecretSerdeValue>,
pub connector_wallets_details: Option<common_utils::pii::SecretSerdeValue>,
pub amount_captured: Option<i64>,
pub access_token: Option<AccessToken>,
pub session_token: Option<String>,
Expand Down Expand Up @@ -56,7 +57,7 @@ pub struct RouterData<Flow, Request, Response> {
pub connector_http_status_code: Option<u16>,
pub external_latency: Option<u128>,
/// Contains apple pay flow type simplified or manual
pub apple_pay_flow: Option<common_enums::enums::ApplePayFlow>,
pub apple_pay_flow: Option<payment_method_data::ApplePayFlow>,

pub frm_metadata: Option<common_utils::pii::SecretSerdeValue>,

Expand Down
2 changes: 2 additions & 0 deletions crates/openapi/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::FeatureMetadata,
api_models::payments::ApplepayConnectorMetadataRequest,
api_models::payments::SessionTokenInfo,
api_models::payments::PaymentProcessingDetailsAt,
api_models::payments::PaymentProcessingDetails,
api_models::payments::SwishQrData,
api_models::payments::AirwallexData,
api_models::payments::NoonData,
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod admin;
pub mod api_keys;
pub mod api_locking;
pub mod apple_pay_certificates_migration;
pub mod authentication;
pub mod blocklist;
pub mod cache;
Expand Down
8 changes: 7 additions & 1 deletion crates/router/src/core/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ pub async fn create_payment_connector(
payment_methods_enabled,
test_mode: req.test_mode,
disabled,
metadata: req.metadata,
metadata: req.metadata.clone(),
frm_configs,
connector_label: Some(connector_label.clone()),
business_country: req.business_country,
Expand All @@ -961,6 +961,7 @@ pub async fn create_payment_connector(
applepay_verified_domains: None,
pm_auth_config: req.pm_auth_config.clone(),
status: connector_status,
connector_wallets_details: helpers::get_encrypted_apple_pay_connector_wallets_details(&key_store, &req.metadata).await?,
};

let transaction_type = match req.connector_type {
Expand Down Expand Up @@ -1200,6 +1201,7 @@ pub async fn update_payment_connector(
expected_format: "auth_type and api_key".to_string(),
})?;
let metadata = req.metadata.clone().or(mca.metadata.clone());

let connector_name = mca.connector_name.as_ref();
let connector_enum = api_models::enums::Connector::from_str(connector_name)
.change_context(errors::ApiErrorResponse::InvalidDataValue {
Expand Down Expand Up @@ -1275,6 +1277,10 @@ pub async fn update_payment_connector(
applepay_verified_domains: None,
pm_auth_config: req.pm_auth_config,
status: Some(connector_status),
connector_wallets_details: helpers::get_encrypted_apple_pay_connector_wallets_details(
&key_store, &metadata,
)
.await?,
};

// Profile id should always be present
Expand Down
109 changes: 109 additions & 0 deletions crates/router/src/core/apple_pay_certificates_migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use api_models::apple_pay_certificates_migration;
use common_utils::errors::CustomResult;
use error_stack::ResultExt;
use masking::{PeekInterface, Secret};

use super::{
errors::{self, StorageErrorExt},
payments::helpers,
};
use crate::{
routes::SessionState,
services::{self, logger},
types::{domain::types as domain_types, storage},
};

pub async fn apple_pay_certificates_migration(
state: SessionState,
req: &apple_pay_certificates_migration::ApplePayCertificatesMigrationRequest,
) -> CustomResult<
services::ApplicationResponse<
apple_pay_certificates_migration::ApplePayCertificatesMigrationResponse,
>,
errors::ApiErrorResponse,
> {
let db = state.store.as_ref();

let merchant_id_list = &req.merchant_ids;

let mut migration_successful_merchant_ids = vec![];
let mut migration_failed_merchant_ids = vec![];

for merchant_id in merchant_id_list {
let key_store = state
.store
.get_merchant_key_store_by_merchant_id(
merchant_id,
&state.store.get_master_key().to_vec().into(),
)
.await
.change_context(errors::ApiErrorResponse::InternalServerError)?;

let merchant_connector_accounts = db
.find_merchant_connector_account_by_merchant_id_and_disabled_list(
merchant_id,
true,
&key_store,
)
.await
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)?;

let mut mca_to_update = vec![];

for connector_account in merchant_connector_accounts {
let connector_apple_pay_metadata =
helpers::get_applepay_metadata(connector_account.clone().metadata)
.map_err(|error| {
logger::error!(
"Apple pay metadata parsing failed for {:?} in certificates migrations api {:?}",
connector_account.clone().connector_name,
error
)
})
.ok();
if let Some(apple_pay_metadata) = connector_apple_pay_metadata {
let encrypted_apple_pay_metadata = domain_types::encrypt(
Secret::new(
serde_json::to_value(apple_pay_metadata)
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to serialize apple pay metadata as JSON")?,
),
key_store.key.get_inner().peek(),
)
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Unable to encrypt connector apple pay metadata")?;

let updated_mca =
storage::MerchantConnectorAccountUpdate::ConnectorWalletDetailsUpdate {
connector_wallets_details: encrypted_apple_pay_metadata,
};

mca_to_update.push((connector_account, updated_mca.into()));
}
}

let merchant_connector_accounts_update = db
.update_multiple_merchant_connector_accounts(mca_to_update)
.await;

match merchant_connector_accounts_update {
Ok(_) => {
logger::debug!("Merchant connector accounts updated for merchant id {merchant_id}");
migration_successful_merchant_ids.push(merchant_id.to_string());
}
Err(error) => {
logger::debug!(
"Merchant connector accounts update failed with error {error} for merchant id {merchant_id}");
migration_failed_merchant_ids.push(merchant_id.to_string());
}
};
}

Ok(services::api::ApplicationResponse::Json(
apple_pay_certificates_migration::ApplePayCertificatesMigrationResponse {
migration_successful: migration_successful_merchant_ids,
migration_failed: migration_failed_merchant_ids,
},
))
}
1 change: 1 addition & 0 deletions crates/router/src/core/authentication/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ pub fn construct_router_data<F: Clone, Req, Res>(
address,
auth_type: common_enums::AuthenticationType::NoThreeDs,
connector_meta_data: merchant_connector_account.get_metadata(),
connector_wallets_details: merchant_connector_account.get_connector_wallets_details(),
amount_captured: None,
access_token: None,
session_token: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC
address: self.address.clone(),
auth_type: storage_enums::AuthenticationType::NoThreeDs,
connector_meta_data: None,
connector_wallets_details: None,
amount_captured: None,
request: FraudCheckCheckoutData {
amount: self.payment_attempt.amount.get_amount_as_i64(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub async fn construct_fulfillment_router_data<'a>(
address: PaymentAddress::default(),
auth_type: payment_attempt.authentication_type.unwrap_or_default(),
connector_meta_data: merchant_connector_account.get_metadata(),
connector_wallets_details: merchant_connector_account.get_connector_wallets_details(),
amount_captured: payment_intent
.amount_captured
.map(|amt| amt.get_amount_as_i64()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCh
address: self.address.clone(),
auth_type: storage_enums::AuthenticationType::NoThreeDs,
connector_meta_data: None,
connector_wallets_details: None,
amount_captured: None,
request: FraudCheckRecordReturnData {
amount: self.payment_attempt.amount.get_amount_as_i64(),
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core/fraud_check/flows/sale_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp
address: self.address.clone(),
auth_type: storage_enums::AuthenticationType::NoThreeDs,
connector_meta_data: None,
connector_wallets_details: None,
amount_captured: None,
request: FraudCheckSaleData {
amount: self.payment_attempt.amount.get_amount_as_i64(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl
address: self.address.clone(),
auth_type: storage_enums::AuthenticationType::NoThreeDs,
connector_meta_data: None,
connector_wallets_details: None,
amount_captured: None,
request: FraudCheckTransactionData {
amount: self.payment_attempt.amount.get_amount_as_i64(),
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core/mandate/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub async fn construct_mandate_revoke_router_data(
address: PaymentAddress::default(),
auth_type: diesel_models::enums::AuthenticationType::default(),
connector_meta_data: None,
connector_wallets_details: None,
amount_captured: None,
access_token: None,
session_token: None,
Expand Down
Loading
Loading