mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	fix(payment_method): do not save card in locker in case of error from connector (#1341)
This commit is contained in:
		| @ -31,102 +31,119 @@ pub async fn save_payment_method<F: Clone, FData>( | ||||
| where | ||||
|     FData: mandate::MandateBehaviour, | ||||
| { | ||||
|     let db = &*state.store; | ||||
|     let token_store = state | ||||
|         .conf | ||||
|         .tokenization | ||||
|         .0 | ||||
|         .get(&connector.connector_name.to_string()) | ||||
|         .map(|token_filter| token_filter.long_lived_token) | ||||
|         .unwrap_or(false); | ||||
|     match resp.response { | ||||
|         Ok(_) => { | ||||
|             let db = &*state.store; | ||||
|             let token_store = state | ||||
|                 .conf | ||||
|                 .tokenization | ||||
|                 .0 | ||||
|                 .get(&connector.connector_name.to_string()) | ||||
|                 .map(|token_filter| token_filter.long_lived_token) | ||||
|                 .unwrap_or(false); | ||||
|  | ||||
|     let connector_token = if token_store { | ||||
|         let token = resp | ||||
|             .payment_method_token | ||||
|             .to_owned() | ||||
|             .get_required_value("payment_token")?; | ||||
|         Some((connector, token)) | ||||
|     } else { | ||||
|         None | ||||
|     }; | ||||
|  | ||||
|     let pm_id = if resp.request.get_setup_future_usage().is_some() { | ||||
|         let customer = maybe_customer.to_owned().get_required_value("customer")?; | ||||
|         let payment_method_create_request = helpers::get_payment_method_create_request( | ||||
|             Some(&resp.request.get_payment_method_data()), | ||||
|             Some(resp.payment_method), | ||||
|             payment_method_type, | ||||
|             &customer, | ||||
|         ) | ||||
|         .await?; | ||||
|         let merchant_id = &merchant_account.merchant_id; | ||||
|  | ||||
|         let locker_response = save_in_locker( | ||||
|             state, | ||||
|             merchant_account, | ||||
|             payment_method_create_request.to_owned(), | ||||
|         ) | ||||
|         .await?; | ||||
|         let is_duplicate = locker_response.1; | ||||
|  | ||||
|         if is_duplicate { | ||||
|             let existing_pm = db | ||||
|                 .find_payment_method(&locker_response.0.payment_method_id) | ||||
|                 .await; | ||||
|             match existing_pm { | ||||
|                 Ok(pm) => { | ||||
|                     let pm_metadata = | ||||
|                         create_payment_method_metadata(pm.metadata.as_ref(), connector_token)?; | ||||
|                     if let Some(metadata) = pm_metadata { | ||||
|                         payment_methods::cards::update_payment_method(db, pm, metadata) | ||||
|                             .await | ||||
|                             .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|                             .attach_printable("Failed to add payment method in db")?; | ||||
|                     }; | ||||
|                 } | ||||
|                 Err(error) => { | ||||
|                     match error.current_context() { | ||||
|                         errors::StorageError::DatabaseError(err) => match err.current_context() { | ||||
|                             storage_models::errors::DatabaseError::NotFound => { | ||||
|                                 let pm_metadata = | ||||
|                                     create_payment_method_metadata(None, connector_token)?; | ||||
|                                 payment_methods::cards::create_payment_method( | ||||
|                                     db, | ||||
|                                     &payment_method_create_request, | ||||
|                                     &customer.customer_id, | ||||
|                                     &locker_response.0.payment_method_id, | ||||
|                                     merchant_id, | ||||
|                                     pm_metadata, | ||||
|                                 ) | ||||
|                                 .await | ||||
|                                 .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|                                 .attach_printable("Failed to add payment method in db") | ||||
|                             } | ||||
|                             _ => Err(report!(errors::ApiErrorResponse::InternalServerError)), | ||||
|                         }, | ||||
|                         _ => Err(report!(errors::ApiErrorResponse::InternalServerError)), | ||||
|                     }?; | ||||
|                 } | ||||
|             let connector_token = if token_store { | ||||
|                 let token = resp | ||||
|                     .payment_method_token | ||||
|                     .to_owned() | ||||
|                     .get_required_value("payment_token")?; | ||||
|                 Some((connector, token)) | ||||
|             } else { | ||||
|                 None | ||||
|             }; | ||||
|         } else { | ||||
|             let pm_metadata = create_payment_method_metadata(None, connector_token)?; | ||||
|             payment_methods::cards::create_payment_method( | ||||
|                 db, | ||||
|                 &payment_method_create_request, | ||||
|                 &customer.customer_id, | ||||
|                 &locker_response.0.payment_method_id, | ||||
|                 merchant_id, | ||||
|                 pm_metadata, | ||||
|             ) | ||||
|             .await | ||||
|             .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|             .attach_printable("Failed to add payment method in db")?; | ||||
|         }; | ||||
|         Some(locker_response.0.payment_method_id) | ||||
|     } else { | ||||
|         None | ||||
|     }; | ||||
|     Ok(pm_id) | ||||
|  | ||||
|             let pm_id = if resp.request.get_setup_future_usage().is_some() { | ||||
|                 let customer = maybe_customer.to_owned().get_required_value("customer")?; | ||||
|                 let payment_method_create_request = helpers::get_payment_method_create_request( | ||||
|                     Some(&resp.request.get_payment_method_data()), | ||||
|                     Some(resp.payment_method), | ||||
|                     payment_method_type, | ||||
|                     &customer, | ||||
|                 ) | ||||
|                 .await?; | ||||
|                 let merchant_id = &merchant_account.merchant_id; | ||||
|  | ||||
|                 let locker_response = save_in_locker( | ||||
|                     state, | ||||
|                     merchant_account, | ||||
|                     payment_method_create_request.to_owned(), | ||||
|                 ) | ||||
|                 .await?; | ||||
|                 let is_duplicate = locker_response.1; | ||||
|  | ||||
|                 if is_duplicate { | ||||
|                     let existing_pm = db | ||||
|                         .find_payment_method(&locker_response.0.payment_method_id) | ||||
|                         .await; | ||||
|                     match existing_pm { | ||||
|                         Ok(pm) => { | ||||
|                             let pm_metadata = create_payment_method_metadata( | ||||
|                                 pm.metadata.as_ref(), | ||||
|                                 connector_token, | ||||
|                             )?; | ||||
|                             if let Some(metadata) = pm_metadata { | ||||
|                                 payment_methods::cards::update_payment_method(db, pm, metadata) | ||||
|                                     .await | ||||
|                                     .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|                                     .attach_printable("Failed to add payment method in db")?; | ||||
|                             }; | ||||
|                         } | ||||
|                         Err(error) => { | ||||
|                             match error.current_context() { | ||||
|                                 errors::StorageError::DatabaseError(err) => match err | ||||
|                                     .current_context() | ||||
|                                 { | ||||
|                                     storage_models::errors::DatabaseError::NotFound => { | ||||
|                                         let pm_metadata = | ||||
|                                             create_payment_method_metadata(None, connector_token)?; | ||||
|                                         payment_methods::cards::create_payment_method( | ||||
|                                             db, | ||||
|                                             &payment_method_create_request, | ||||
|                                             &customer.customer_id, | ||||
|                                             &locker_response.0.payment_method_id, | ||||
|                                             merchant_id, | ||||
|                                             pm_metadata, | ||||
|                                         ) | ||||
|                                         .await | ||||
|                                         .change_context( | ||||
|                                             errors::ApiErrorResponse::InternalServerError, | ||||
|                                         ) | ||||
|                                         .attach_printable("Failed to add payment method in db") | ||||
|                                     } | ||||
|                                     _ => { | ||||
|                                         Err(report!(errors::ApiErrorResponse::InternalServerError) | ||||
|                                             .attach_printable( | ||||
|                                                 "Database Error while finding payment method", | ||||
|                                             )) | ||||
|                                     } | ||||
|                                 }, | ||||
|                                 _ => Err(report!(errors::ApiErrorResponse::InternalServerError) | ||||
|                                     .attach_printable("Error while finding payment method")), | ||||
|                             }?; | ||||
|                         } | ||||
|                     }; | ||||
|                 } else { | ||||
|                     let pm_metadata = create_payment_method_metadata(None, connector_token)?; | ||||
|                     payment_methods::cards::create_payment_method( | ||||
|                         db, | ||||
|                         &payment_method_create_request, | ||||
|                         &customer.customer_id, | ||||
|                         &locker_response.0.payment_method_id, | ||||
|                         merchant_id, | ||||
|                         pm_metadata, | ||||
|                     ) | ||||
|                     .await | ||||
|                     .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|                     .attach_printable("Failed to add payment method in db")?; | ||||
|                 }; | ||||
|                 Some(locker_response.0.payment_method_id) | ||||
|             } else { | ||||
|                 None | ||||
|             }; | ||||
|             Ok(pm_id) | ||||
|         } | ||||
|         Err(_) => Ok(None), | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub async fn save_in_locker( | ||||
|  | ||||
		Reference in New Issue
	
	Block a user