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: insert merchant account and merchant key store in a db transaction #2663

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
8 changes: 8 additions & 0 deletions crates/diesel_models/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ pub enum DatabaseError {
NoFieldsToUpdate,
#[error("An error occurred when generating typed SQL query")]
QueryGenerationFailed,
#[error("DB transaction failure")]
TransactionFailed(String),
// InsertFailed,
#[error("An unknown error occurred")]
Others,
}

impl From<diesel::result::Error> for DatabaseError {
fn from(err: diesel::result::Error) -> Self {
Self::TransactionFailed(err.to_string())
}
}
4 changes: 0 additions & 4 deletions crates/router/src/core/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@ pub async fn create_merchant_account(
.payment_response_hash_key
.or(Some(generate_cryptographically_secure_random_string(64)));

db.insert_merchant_key_store(key_store.clone(), &master_key.to_vec().into())
.await
.to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)?;

let parent_merchant_id = get_parent_merchant(
db,
req.sub_merchants_enabled,
Expand Down
41 changes: 29 additions & 12 deletions crates/router/src/db/merchant_account.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use async_bb8_diesel::AsyncConnection;
use common_utils::ext_traits::AsyncExt;
use error_stack::{IntoReport, ResultExt};
#[cfg(feature = "accounts_cache")]
Expand Down Expand Up @@ -72,20 +73,36 @@ impl MerchantAccountInterface for Store {
async fn insert_merchant(
&self,
merchant_account: domain::MerchantAccount,
merchant_key_store: &domain::MerchantKeyStore,
merchant_key_store: domain::MerchantKeyStore,
) -> CustomResult<domain::MerchantAccount, errors::StorageError> {
let conn = connection::pg_connection_write(self).await?;
merchant_account
.construct_new()
.await
.change_context(errors::StorageError::EncryptionError)?
.insert(&conn)
.await
.map_err(Into::into)
.into_report()?
.convert(merchant_key_store.key.get_inner())
.await
.change_context(errors::StorageError::DecryptionError)

conn.transaction_async(|e| async move {
let key_store = merchant_key_store
.construct_new()
.await
.change_context(errors::StorageError::EncryptionError)?
.insert(&e)
.await
.map_err(Into::into)
.into_report()?
.convert(self.get_master_key())
.await
.change_context(errors::StorageError::DecryptionError);

merchant_account
.construct_new()
.await
.change_context(errors::StorageError::EncryptionError)?
.insert(&e)
.await
.map_err(Into::into)
.into_report()?
.convert(merchant_key_store.key.get_inner())
.await
.change_context(errors::StorageError::DecryptionError)
})
.await
}

async fn find_merchant_account_by_merchant_id(
Expand Down
3 changes: 3 additions & 0 deletions crates/storage_impl/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ impl Into<DataStorageError> for &StorageError {
storage_errors::DatabaseError::QueryGenerationFailed => {
DataStorageError::DatabaseError("Query generation failed".to_string())
}
storage_errors::DatabaseError::TransactionFailed(e) => {
DataStorageError::DatabaseError(e.to_string())
}
storage_errors::DatabaseError::Others => {
DataStorageError::DatabaseError("Unknown database error".to_string())
}
Expand Down
Loading