Bug: Set the PM as default if there is no Default PM for a customer




diff --git a/crates/router/src/core/payment_methods/cards.rs b/crates/router/src/core/payment_methods/cards.rs
index ce7f48405e2..712b9a0edd7 100644
--- a/crates/router/src/core/payment_methods/cards.rs
+++ b/crates/router/src/core/payment_methods/cards.rs
@@ -84,7 +84,8 @@ pub async fn create_payment_method(
     payment_method_data: Option<Encryption>,
     key_store: &domain::MerchantKeyStore,
 ) -> errors::CustomResult<storage::PaymentMethod, errors::ApiErrorResponse> {
-    db.find_customer_by_customer_id_merchant_id(customer_id, merchant_id, key_store)
+    let customer = db
+        .find_customer_by_customer_id_merchant_id(customer_id, merchant_id, key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
 
@@ -106,6 +107,17 @@ pub async fn create_payment_method(
         .change_context(errors::ApiErrorResponse::InternalServerError)
         .attach_printable("Failed to add payment method in db")?;
 
+    if customer.default_payment_method_id.is_none() {
+        let _ = set_default_payment_method(
+            db,
+            merchant_id.to_string(),
+            key_store.clone(),
+            customer_id,
+            payment_method_id.to_owned(),
+        )
+        .await
+        .map_err(|err| logger::error!(error=?err,"Failed to set the payment method as default"));
+    }
     Ok(response)
 }
 
@@ -3080,20 +3092,15 @@ async fn get_bank_account_connector_details(
     }
 }
 pub async fn set_default_payment_method(
-    state: routes::AppState,
-    merchant_account: domain::MerchantAccount,
+    db: &dyn db::StorageInterface,
+    merchant_id: String,
     key_store: domain::MerchantKeyStore,
     customer_id: &str,
     payment_method_id: String,
 ) -> errors::RouterResponse<CustomerDefaultPaymentMethodResponse> {
-    let db = &*state.store;
     //check for the customer
     let customer = db
-        .find_customer_by_customer_id_merchant_id(
-            customer_id,
-            &merchant_account.merchant_id,
-            &key_store,
-        )
+        .find_customer_by_customer_id_merchant_id(customer_id, &merchant_id, &key_store)
         .await
         .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)?;
     // check for the presence of payment_method
@@ -3103,8 +3110,7 @@ pub async fn set_default_payment_method(
         .to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
 
     utils::when(
-        payment_method.customer_id != customer_id
-            && payment_method.merchant_id != merchant_account.merchant_id,
+        payment_method.customer_id != customer_id || payment_method.merchant_id != merchant_id,
         || {
             Err(errors::ApiErrorResponse::PreconditionFailed {
                 message: "The payment_method_id is not valid".to_string(),
@@ -3124,14 +3130,14 @@ pub async fn set_default_payment_method(
     )?;
 
     let customer_update = CustomerUpdate::UpdateDefaultPaymentMethod {
-        default_payment_method_id: Some(payment_method_id.clone()),
+        default_payment_method_id: Some(payment_method_id.to_owned()),
     };
 
     // update the db with the default payment method id
     let updated_customer_details = db
         .update_customer_by_customer_id_merchant_id(
             customer_id.to_owned(),
-            merchant_account.merchant_id,
+            merchant_id.to_owned(),
             customer_update,
             &key_store,
         )
diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs
index 1f793e2e185..baf395b230c 100644
--- a/crates/router/src/core/payments/tokenization.rs
+++ b/crates/router/src/core/payments/tokenization.rs
@@ -348,6 +348,7 @@ where
                         } else {
                             None
                         };
+
                         resp.payment_method_id = generate_id(consts::ID_LENGTH, "pm");
                         payment_methods::cards::create_payment_method(
                             db,
diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs
index 5469f981659..939cfaf93dc 100644
--- a/crates/router/src/routes/payment_methods.rs
+++ b/crates/router/src/routes/payment_methods.rs
@@ -275,15 +275,16 @@ pub async fn default_payment_method_set_api(
             Ok(auth) => auth,
             Err(err) => return api::log_and_return_error_response(err),
         };
+    let db = &*state.store.clone();
     Box::pin(api::server_wrap(
         flow,
         state,
         &req,
         payload,
-        |state, auth: auth::AuthenticationData, default_payment_method| {
+        |_state, auth: auth::AuthenticationData, default_payment_method| {
             cards::set_default_payment_method(
-                state,
-                auth.merchant_account,
+                db,
+                auth.merchant_account.merchant_id,
                 auth.key_store,
                 &customer_id,
                 default_payment_method.payment_method_id,

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description

Set the initial payment method as default until its explicitly set


### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?

- Create an MA and a MCA
- Do a save card payment
- Do a ListPaymentMethodsForCustomers the default flag would be set to true for the initial card
- Do a save card payment, with other card , its default flag would be set to false, until explicitly set to true , using the endpoint `/customers/:customer_id/payment_methods/:payment_method_id/default`
```
curl --location --request POST 'http://localhost:8080/customers/{customer_id}/payment_methods/{payment_method_id}/set' \
--header 'Accept: application/json' \
--header 'api-key: epk_bf2209db8af14c04b811bce74e0d1202'
```
<img width="1296" alt="Screenshot 2024-03-06 at 12 19 31 AM" src="https://github.com/juspay/hyperswitch/assets/55580080/0fda5a3c-4f3a-4675-9b0c-b82958d28fe9">


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [ ] I formatted the code `cargo +nightly fmt --all`
- [ ] I addressed lints thrown by `cargo clippy`
- [ ] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
