mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(payment_methods): populate connector_customer during customer creation step in payment methods migrate flow (#8319)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -57,7 +57,7 @@ pub async fn customer_create(
|
||||
let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
|
||||
domain::Context(auth.merchant_account, auth.key_store),
|
||||
));
|
||||
customers::create_customer(state, merchant_context, req)
|
||||
customers::create_customer(state, merchant_context, req, None)
|
||||
},
|
||||
&auth::HeaderAuth(auth::ApiKeyAuth {
|
||||
is_connected_allowed: false,
|
||||
|
||||
@ -27,7 +27,7 @@ use crate::{
|
||||
routes::{metrics, SessionState},
|
||||
services,
|
||||
types::{
|
||||
api::customers,
|
||||
api::{customers, payment_methods as payment_methods_api},
|
||||
domain::{self, types},
|
||||
storage::{self, enums},
|
||||
transformers::ForeignFrom,
|
||||
@ -41,6 +41,7 @@ pub async fn create_customer(
|
||||
state: SessionState,
|
||||
merchant_context: domain::MerchantContext,
|
||||
customer_data: customers::CustomerRequest,
|
||||
connector_customer_details: Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
) -> errors::CustomerResponse<customers::CustomerResponse> {
|
||||
let db: &dyn StorageInterface = state.store.as_ref();
|
||||
let key_manager_state = &(&state).into();
|
||||
@ -69,6 +70,7 @@ pub async fn create_customer(
|
||||
|
||||
let domain_customer = customer_data
|
||||
.create_domain_model_from_request(
|
||||
&connector_customer_details,
|
||||
db,
|
||||
&merchant_reference_id,
|
||||
&merchant_context,
|
||||
@ -94,6 +96,7 @@ pub async fn create_customer(
|
||||
trait CustomerCreateBridge {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
db: &'a dyn StorageInterface,
|
||||
merchant_reference_id: &'a Option<id_type::CustomerId>,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
@ -112,6 +115,7 @@ trait CustomerCreateBridge {
|
||||
impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
db: &'a dyn StorageInterface,
|
||||
merchant_reference_id: &'a Option<id_type::CustomerId>,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
@ -171,6 +175,15 @@ impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
domain::FromRequestEncryptableCustomer::from_encryptable(encrypted_data)
|
||||
.change_context(errors::CustomersErrorResponse::InternalServerError)?;
|
||||
|
||||
let connector_customer = connector_customer_details.as_ref().map(|details| {
|
||||
let merchant_connector_id = details.merchant_connector_id.get_string_repr().to_string();
|
||||
let connector_customer_id = details.connector_customer_id.to_string();
|
||||
let object = serde_json::json!({
|
||||
merchant_connector_id: connector_customer_id
|
||||
});
|
||||
pii::SecretSerdeValue::new(object)
|
||||
});
|
||||
|
||||
Ok(domain::Customer {
|
||||
customer_id: merchant_reference_id
|
||||
.to_owned()
|
||||
@ -188,7 +201,7 @@ impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
description: self.description.clone(),
|
||||
phone_country_code: self.phone_country_code.clone(),
|
||||
metadata: self.metadata.clone(),
|
||||
connector_customer: None,
|
||||
connector_customer,
|
||||
address_id: address_from_db.clone().map(|addr| addr.address_id),
|
||||
created_at: common_utils::date_time::now(),
|
||||
modified_at: common_utils::date_time::now(),
|
||||
@ -214,6 +227,7 @@ impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
_db: &'a dyn StorageInterface,
|
||||
merchant_reference_id: &'a Option<id_type::CustomerId>,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
@ -283,6 +297,15 @@ impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
domain::FromRequestEncryptableCustomer::from_encryptable(encrypted_data)
|
||||
.change_context(errors::CustomersErrorResponse::InternalServerError)?;
|
||||
|
||||
let connector_customer = connector_customer_details.as_ref().map(|details| {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
map.insert(
|
||||
details.merchant_connector_id.clone(),
|
||||
details.connector_customer_id.to_string(),
|
||||
);
|
||||
common_types::customers::ConnectorCustomerMap::new(map)
|
||||
});
|
||||
|
||||
Ok(domain::Customer {
|
||||
id: id_type::GlobalCustomerId::generate(&state.conf.cell_information.id),
|
||||
merchant_reference_id: merchant_reference_id.to_owned(),
|
||||
@ -299,7 +322,7 @@ impl CustomerCreateBridge for customers::CustomerRequest {
|
||||
description: self.description.clone(),
|
||||
phone_country_code: self.phone_country_code.clone(),
|
||||
metadata: self.metadata.clone(),
|
||||
connector_customer: None,
|
||||
connector_customer,
|
||||
created_at: common_utils::date_time::now(),
|
||||
modified_at: common_utils::date_time::now(),
|
||||
default_payment_method_id: None,
|
||||
@ -1024,6 +1047,7 @@ pub async fn update_customer(
|
||||
let updated_customer = update_customer
|
||||
.request
|
||||
.create_domain_model_from_request(
|
||||
&None,
|
||||
db,
|
||||
&merchant_context,
|
||||
key_manager_state,
|
||||
@ -1039,6 +1063,7 @@ pub async fn update_customer(
|
||||
trait CustomerUpdateBridge {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
db: &'a dyn StorageInterface,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
key_manager_state: &'a KeyManagerState,
|
||||
@ -1211,6 +1236,7 @@ impl VerifyIdForUpdateCustomer<'_> {
|
||||
impl CustomerUpdateBridge for customers::CustomerUpdateRequest {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
_connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
db: &'a dyn StorageInterface,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
key_manager_state: &'a KeyManagerState,
|
||||
@ -1315,6 +1341,7 @@ impl CustomerUpdateBridge for customers::CustomerUpdateRequest {
|
||||
impl CustomerUpdateBridge for customers::CustomerUpdateRequest {
|
||||
async fn create_domain_model_from_request<'a>(
|
||||
&'a self,
|
||||
connector_customer_details: &'a Option<payment_methods_api::ConnectorCustomerDetails>,
|
||||
db: &'a dyn StorageInterface,
|
||||
merchant_context: &'a domain::MerchantContext,
|
||||
key_manager_state: &'a KeyManagerState,
|
||||
@ -1432,11 +1459,18 @@ impl CustomerUpdateBridge for customers::CustomerUpdateRequest {
|
||||
|
||||
pub async fn migrate_customers(
|
||||
state: SessionState,
|
||||
customers: Vec<customers::CustomerRequest>,
|
||||
customers_migration: Vec<payment_methods_api::PaymentMethodCustomerMigrate>,
|
||||
merchant_context: domain::MerchantContext,
|
||||
) -> errors::CustomerResponse<()> {
|
||||
for customer in customers {
|
||||
match create_customer(state.clone(), merchant_context.clone(), customer).await {
|
||||
for customer_migration in customers_migration {
|
||||
match create_customer(
|
||||
state.clone(),
|
||||
merchant_context.clone(),
|
||||
customer_migration.customer,
|
||||
customer_migration.connector_customer_details,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => (),
|
||||
Err(e) => match e.current_context() {
|
||||
errors::CustomersErrorResponse::CustomerAlreadyExists => (),
|
||||
|
||||
@ -25,7 +25,7 @@ pub async fn customers_create(
|
||||
let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
|
||||
domain::Context(auth.merchant_account, auth.key_store),
|
||||
));
|
||||
create_customer(state, merchant_context, req)
|
||||
create_customer(state, merchant_context, req, None)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::V2ApiKeyAuth {
|
||||
@ -58,7 +58,7 @@ pub async fn customers_create(
|
||||
let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
|
||||
domain::Context(auth.merchant_account, auth.key_store),
|
||||
));
|
||||
create_customer(state, merchant_context, req)
|
||||
create_customer(state, merchant_context, req, None)
|
||||
},
|
||||
auth::auth_type(
|
||||
&auth::HeaderAuth(auth::ApiKeyAuth {
|
||||
|
||||
@ -14,6 +14,8 @@ use hyperswitch_domain_models::{
|
||||
use router_env::{instrument, logger, tracing, Flow};
|
||||
|
||||
use super::app::{AppState, SessionState};
|
||||
#[cfg(all(feature = "v1", any(feature = "olap", feature = "oltp")))]
|
||||
use crate::core::{customers, payment_methods::tokenize};
|
||||
use crate::{
|
||||
core::{
|
||||
api_locking,
|
||||
@ -27,11 +29,6 @@ use crate::{
|
||||
storage::payment_method::PaymentTokenData,
|
||||
},
|
||||
};
|
||||
#[cfg(all(feature = "v1", any(feature = "olap", feature = "oltp")))]
|
||||
use crate::{
|
||||
core::{customers, payment_methods::tokenize},
|
||||
types::api::customers::CustomerRequest,
|
||||
};
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsCreate))]
|
||||
@ -360,7 +357,12 @@ pub async fn migrate_payment_methods(
|
||||
customers::migrate_customers(
|
||||
state.clone(),
|
||||
req.iter()
|
||||
.map(|e| CustomerRequest::from((e.clone(), merchant_id.clone())))
|
||||
.map(|e| {
|
||||
payment_methods::PaymentMethodCustomerMigrate::from((
|
||||
e.clone(),
|
||||
merchant_id.clone(),
|
||||
))
|
||||
})
|
||||
.collect(),
|
||||
merchant_context.clone(),
|
||||
)
|
||||
|
||||
@ -1,30 +1,32 @@
|
||||
#[cfg(feature = "v2")]
|
||||
pub use api_models::payment_methods::{
|
||||
CardDetail, CardDetailFromLocker, CardDetailsPaymentMethod, CardNetworkTokenizeRequest,
|
||||
CardNetworkTokenizeResponse, CardType, CustomerPaymentMethodResponseItem,
|
||||
DeleteTokenizeByTokenRequest, GetTokenizePayloadRequest, GetTokenizePayloadResponse,
|
||||
ListCountriesCurrenciesRequest, MigrateCardDetail, NetworkTokenDetailsPaymentMethod,
|
||||
NetworkTokenDetailsResponse, NetworkTokenResponse, PaymentMethodCollectLinkRenderRequest,
|
||||
PaymentMethodCollectLinkRequest, PaymentMethodCreate, PaymentMethodCreateData,
|
||||
PaymentMethodDeleteResponse, PaymentMethodId, PaymentMethodIntentConfirm,
|
||||
PaymentMethodIntentCreate, PaymentMethodListData, PaymentMethodListRequest,
|
||||
PaymentMethodListResponseForSession, PaymentMethodMigrate, PaymentMethodMigrateResponse,
|
||||
PaymentMethodResponse, PaymentMethodResponseData, PaymentMethodUpdate, PaymentMethodUpdateData,
|
||||
PaymentMethodsData, TokenDataResponse, TokenDetailsResponse, TokenizePayloadEncrypted,
|
||||
TokenizePayloadRequest, TokenizedCardValue1, TokenizedCardValue2, TokenizedWalletValue1,
|
||||
TokenizedWalletValue2, TotalPaymentMethodCountResponse,
|
||||
CardNetworkTokenizeResponse, CardType, ConnectorCustomerDetails,
|
||||
CustomerPaymentMethodResponseItem, DeleteTokenizeByTokenRequest, GetTokenizePayloadRequest,
|
||||
GetTokenizePayloadResponse, ListCountriesCurrenciesRequest, MigrateCardDetail,
|
||||
NetworkTokenDetailsPaymentMethod, NetworkTokenDetailsResponse, NetworkTokenResponse,
|
||||
PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest, PaymentMethodCreate,
|
||||
PaymentMethodCreateData, PaymentMethodCustomerMigrate, PaymentMethodDeleteResponse,
|
||||
PaymentMethodId, PaymentMethodIntentConfirm, PaymentMethodIntentCreate, PaymentMethodListData,
|
||||
PaymentMethodListRequest, PaymentMethodListResponseForSession, PaymentMethodMigrate,
|
||||
PaymentMethodMigrateResponse, PaymentMethodResponse, PaymentMethodResponseData,
|
||||
PaymentMethodUpdate, PaymentMethodUpdateData, PaymentMethodsData, TokenDataResponse,
|
||||
TokenDetailsResponse, TokenizePayloadEncrypted, TokenizePayloadRequest, TokenizedCardValue1,
|
||||
TokenizedCardValue2, TokenizedWalletValue1, TokenizedWalletValue2,
|
||||
TotalPaymentMethodCountResponse,
|
||||
};
|
||||
#[cfg(feature = "v1")]
|
||||
pub use api_models::payment_methods::{
|
||||
CardDetail, CardDetailFromLocker, CardDetailsPaymentMethod, CardNetworkTokenizeRequest,
|
||||
CardNetworkTokenizeResponse, CustomerPaymentMethod, CustomerPaymentMethodsListResponse,
|
||||
DefaultPaymentMethod, DeleteTokenizeByTokenRequest, GetTokenizePayloadRequest,
|
||||
GetTokenizePayloadResponse, ListCountriesCurrenciesRequest, MigrateCardDetail,
|
||||
PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest, PaymentMethodCreate,
|
||||
PaymentMethodCreateData, PaymentMethodDeleteResponse, PaymentMethodId,
|
||||
PaymentMethodListRequest, PaymentMethodListResponse, PaymentMethodMigrate,
|
||||
PaymentMethodMigrateResponse, PaymentMethodResponse, PaymentMethodUpdate, PaymentMethodsData,
|
||||
TokenizeCardRequest, TokenizeDataRequest, TokenizePayloadEncrypted, TokenizePayloadRequest,
|
||||
CardNetworkTokenizeResponse, ConnectorCustomerDetails, CustomerPaymentMethod,
|
||||
CustomerPaymentMethodsListResponse, DefaultPaymentMethod, DeleteTokenizeByTokenRequest,
|
||||
GetTokenizePayloadRequest, GetTokenizePayloadResponse, ListCountriesCurrenciesRequest,
|
||||
MigrateCardDetail, PaymentMethodCollectLinkRenderRequest, PaymentMethodCollectLinkRequest,
|
||||
PaymentMethodCreate, PaymentMethodCreateData, PaymentMethodCustomerMigrate,
|
||||
PaymentMethodDeleteResponse, PaymentMethodId, PaymentMethodListRequest,
|
||||
PaymentMethodListResponse, PaymentMethodMigrate, PaymentMethodMigrateResponse,
|
||||
PaymentMethodResponse, PaymentMethodUpdate, PaymentMethodsData, TokenizeCardRequest,
|
||||
TokenizeDataRequest, TokenizePayloadEncrypted, TokenizePayloadRequest,
|
||||
TokenizePaymentMethodRequest, TokenizedCardValue1, TokenizedCardValue2, TokenizedWalletValue1,
|
||||
TokenizedWalletValue2,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user