mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 12:06:56 +08:00
feat(payment_methods): add support to migrate existing customer PMs from processor to hyperswitch (#5306)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,18 +1,25 @@
|
||||
use actix_multipart::form::MultipartForm;
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use common_utils::{errors::CustomResult, id_type};
|
||||
use diesel_models::enums::IntentStatus;
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::merchant_key_store::MerchantKeyStore;
|
||||
use router_env::{instrument, logger, tracing, Flow};
|
||||
|
||||
use super::app::{AppState, SessionState};
|
||||
use crate::{
|
||||
core::{
|
||||
api_locking, errors,
|
||||
payment_methods::{self as payment_methods_routes, cards},
|
||||
api_locking, customers, errors,
|
||||
errors::utils::StorageErrorExt,
|
||||
payment_methods::{self as payment_methods_routes, cards, migration},
|
||||
},
|
||||
services::{api, authentication as auth, authorization::permissions::Permission},
|
||||
types::{
|
||||
api::payment_methods::{self, PaymentMethodId},
|
||||
api::{
|
||||
customers::CustomerRequest,
|
||||
payment_methods::{self, PaymentMethodId},
|
||||
},
|
||||
domain,
|
||||
storage::payment_method::PaymentTokenData,
|
||||
},
|
||||
utils::Encode,
|
||||
@ -59,7 +66,84 @@ pub async fn migrate_payment_method_api(
|
||||
state,
|
||||
&req,
|
||||
json_payload.into_inner(),
|
||||
|state, _, req, _| async move { Box::pin(cards::migrate_payment_method(state, req)).await },
|
||||
|state, _, req, _| async move {
|
||||
let merchant_id = req.merchant_id.clone();
|
||||
let (key_store, merchant_account) = get_merchant_account(&state, &merchant_id).await?;
|
||||
Box::pin(cards::migrate_payment_method(
|
||||
state,
|
||||
req,
|
||||
&merchant_id,
|
||||
&merchant_account,
|
||||
&key_store,
|
||||
))
|
||||
.await
|
||||
},
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_merchant_account(
|
||||
state: &SessionState,
|
||||
merchant_id: &str,
|
||||
) -> CustomResult<(MerchantKeyStore, domain::MerchantAccount), errors::ApiErrorResponse> {
|
||||
let key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
merchant_id,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
||||
|
||||
let merchant_account = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(merchant_id, &key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
||||
Ok((key_store, merchant_account))
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsMigrate))]
|
||||
pub async fn migrate_payment_methods(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
MultipartForm(form): MultipartForm<migration::PaymentMethodsMigrateForm>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::PaymentMethodsMigrate;
|
||||
let (merchant_id, records) = match migration::get_payment_method_records(form) {
|
||||
Ok((merchant_id, records)) => (merchant_id, records),
|
||||
Err(e) => return api::log_and_return_error_response(e.into()),
|
||||
};
|
||||
let merchant_id = merchant_id.as_str();
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
records,
|
||||
|state, _, req, _| async move {
|
||||
let (key_store, merchant_account) = get_merchant_account(&state, merchant_id).await?;
|
||||
// Create customers if they are not already present
|
||||
customers::migrate_customers(
|
||||
state.clone(),
|
||||
req.iter()
|
||||
.map(|e| CustomerRequest::from(e.clone()))
|
||||
.collect(),
|
||||
merchant_account.clone(),
|
||||
key_store.clone(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
Box::pin(migration::migrate_payment_methods(
|
||||
state,
|
||||
req,
|
||||
merchant_id,
|
||||
&merchant_account,
|
||||
&key_store,
|
||||
))
|
||||
.await
|
||||
},
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user