mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat: delete customer data in compliance with GDPR regulations (#64)
This commit is contained in:
@ -2,12 +2,16 @@ use error_stack::ResultExt;
|
||||
use router_env::{tracing, tracing::instrument};
|
||||
|
||||
use crate::{
|
||||
core::errors::{self, RouterResponse, StorageErrorExt},
|
||||
core::{
|
||||
errors::{self, RouterResponse, StorageErrorExt},
|
||||
payment_methods::cards,
|
||||
},
|
||||
db::StorageInterface,
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
api::customers::{self, CustomerRequestExt},
|
||||
storage,
|
||||
storage::{self, enums},
|
||||
},
|
||||
};
|
||||
|
||||
@ -63,20 +67,99 @@ pub async fn retrieve_customer(
|
||||
Ok(services::BachResponse::Json(response.into()))
|
||||
}
|
||||
|
||||
#[instrument(skip(db))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn delete_customer(
|
||||
db: &dyn StorageInterface,
|
||||
state: &AppState,
|
||||
merchant_account: storage::MerchantAccount,
|
||||
req: customers::CustomerId,
|
||||
) -> RouterResponse<customers::CustomerDeleteResponse> {
|
||||
let response = db
|
||||
.delete_customer_by_customer_id_merchant_id(&req.customer_id, &merchant_account.merchant_id)
|
||||
let db = &state.store;
|
||||
|
||||
let cust = db
|
||||
.find_customer_by_customer_id_merchant_id(&req.customer_id, &merchant_account.merchant_id)
|
||||
.await
|
||||
.map(|response| customers::CustomerDeleteResponse {
|
||||
customer_id: req.customer_id,
|
||||
deleted: response,
|
||||
})
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
|
||||
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
|
||||
if cust.name == Some("Redacted".to_string()) {
|
||||
Err(errors::ApiErrorResponse::CustomerRedacted)?
|
||||
}
|
||||
|
||||
let customer_mandates = db
|
||||
.find_mandate_by_merchant_id_customer_id(&merchant_account.merchant_id, &req.customer_id)
|
||||
.await
|
||||
.map_err(|err| err.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||
|
||||
for mandate in customer_mandates.into_iter() {
|
||||
if mandate.mandate_status == enums::MandateStatus::Active {
|
||||
Err(errors::ApiErrorResponse::MandateActive)?
|
||||
}
|
||||
}
|
||||
|
||||
let customer_payment_methods = db
|
||||
.find_payment_method_by_customer_id_merchant_id_list(
|
||||
&req.customer_id,
|
||||
&merchant_account.merchant_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
err.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
|
||||
})?;
|
||||
for pm in customer_payment_methods.into_iter() {
|
||||
if pm.payment_method == enums::PaymentMethodType::Card {
|
||||
cards::delete_card(state, &merchant_account.merchant_id, &pm.payment_method_id).await?;
|
||||
}
|
||||
db.delete_payment_method_by_merchant_id_payment_method_id(
|
||||
&merchant_account.merchant_id,
|
||||
&pm.payment_method_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
|
||||
})?;
|
||||
}
|
||||
|
||||
let update_address = storage::AddressUpdate::Update {
|
||||
city: Some("Redacted".to_string()),
|
||||
country: Some("Redacted".to_string()),
|
||||
line1: Some("Redacted".to_string().into()),
|
||||
line2: Some("Redacted".to_string().into()),
|
||||
line3: Some("Redacted".to_string().into()),
|
||||
state: Some("Redacted".to_string().into()),
|
||||
zip: Some("Redacted".to_string().into()),
|
||||
first_name: Some("Redacted".to_string().into()),
|
||||
last_name: Some("Redacted".to_string().into()),
|
||||
phone_number: Some("Redacted".to_string().into()),
|
||||
country_code: Some("Redacted".to_string()),
|
||||
};
|
||||
db.update_address_by_merchant_id_customer_id(
|
||||
&req.customer_id,
|
||||
&merchant_account.merchant_id,
|
||||
update_address,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::AddressNotFound)?;
|
||||
|
||||
let updated_customer = storage::CustomerUpdate::Update {
|
||||
name: Some("Redacted".to_string()),
|
||||
email: Some("Redacted".to_string().into()),
|
||||
phone: Some("Redacted".to_string().into()),
|
||||
description: Some("Redacted".to_string()),
|
||||
phone_country_code: Some("Redacted".to_string()),
|
||||
metadata: None,
|
||||
};
|
||||
db.update_customer_by_customer_id_merchant_id(
|
||||
req.customer_id.clone(),
|
||||
merchant_account.merchant_id,
|
||||
updated_customer,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::CustomerNotFound)?;
|
||||
|
||||
let response = customers::CustomerDeleteResponse {
|
||||
customer_id: req.customer_id,
|
||||
customer_deleted: true,
|
||||
address_deleted: true,
|
||||
payment_methods_deleted: true,
|
||||
};
|
||||
Ok(services::BachResponse::Json(response))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user