[Card benefits] Implement flat rate benefits blocklist

This change introduces the flat rate benefit blocking logic which
allows us to block flat rate benefit shown on certain merchant.

This change also includes replacing benefit related issuer id usage
with benefit source.

Design doc: go/pay-autofill-chrome-scaling-benefits-design,

Bug: 404867246
Change-Id: I19cc1b66721f99a2b5ab9a22aa6acbae15a900dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6565423
Reviewed-by: Stephen McGruer <smcgruer@chromium.org>
Commit-Queue: Yishui Liu <yishuil@google.com>
Reviewed-by: Sophie Chang <sophiechang@chromium.org>
Reviewed-by: Vinny Persky <vinnypersky@google.com>
Cr-Commit-Position: refs/heads/main@{#1472688}
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
index ee42c6894..9b42bf5 100644
--- a/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
+++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager.cc
@@ -684,7 +684,7 @@
   if (optimization_guide) {
     CreditCardCategoryBenefit::BenefitCategory category_benefit_type =
         optimization_guide->AttemptToGetEligibleCreditCardBenefitCategory(
-            credit_card.issuer_id(), origin.GetURL());
+            credit_card.benefit_source(), origin.GetURL());
     if (category_benefit_type !=
         CreditCardCategoryBenefit::BenefitCategory::kUnknownBenefitCategory) {
       std::optional<CreditCardCategoryBenefit> category_benefit =
@@ -700,7 +700,16 @@
   std::optional<CreditCardFlatRateBenefit> flat_rate_benefit =
       GetFlatRateBenefitByInstrumentId(benefit_instrument_id);
   if (flat_rate_benefit && flat_rate_benefit->IsActiveBenefit()) {
-    return flat_rate_benefit->benefit_description();
+    // Return empty string if flat rate benefit is blocked on the current
+    // merchant.
+    return base::FeatureList::IsEnabled(
+               features::kAutofillEnableFlatRateCardBenefitsBlocklist) &&
+                   optimization_guide &&
+                   optimization_guide
+                       ->ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(
+                           origin.GetURL())
+               ? std::u16string()
+               : flat_rate_benefit->benefit_description();
   }
 
   // No eligible benefit to display.
diff --git a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
index 0e081ea..562fbe8b 100644
--- a/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
+++ b/components/autofill/core/browser/data_manager/payments/payments_data_manager_unittest.cc
@@ -2835,6 +2835,10 @@
     ResetPaymentsDataManager(false, app_locale());
   }
   const std::string& app_locale() { return GetParam(); }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_{
+      features::kAutofillEnableFlatRateCardBenefitsBlocklist};
 };
 
 // Tests that card benefits should be blocked if the app locale is not en-US or
@@ -2845,6 +2849,89 @@
             app_locale() == "en-US" || app_locale() == "en-GB");
 }
 
+// Tests that card flat rate benefits should be blocked when benefit suggestions
+// are disabled for the given url.
+TEST_P(PaymentsDataManagerShouldBlockBenefitsTest,
+       BlockedUrlForFlateRateBenefit) {
+  if (app_locale() != "en-US" && app_locale() != "en-GB") {
+    GTEST_SKIP() << "This test should not run for not supported app locale.";
+  }
+
+  const url::Origin origin =
+      url::Origin::Create(GURL("https://example-blocked-url.com/"));
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+
+  // Add flat rate benefits and linked card.
+  CreditCardFlatRateBenefit flat_rate_benefit =
+      test::GetActiveCreditCardFlatRateBenefit();
+  CreditCard card = test::GetMaskedServerCard();
+  test_api(flat_rate_benefit)
+      .SetLinkedCardInstrumentId(
+          CreditCardBenefitBase::LinkedCardInstrumentId(card.instrument_id()));
+  test_api(payments_data_manager()).AddServerCreditCard(card);
+  payments_data_manager().AddCreditCardBenefitForTest(
+      std::move(flat_rate_benefit));
+
+  EXPECT_TRUE(payments_data_manager()
+                  .GetApplicableBenefitDescriptionForCardAndOrigin(
+                      test::GetMaskedServerCard(), origin,
+                      autofill_client()->GetAutofillOptimizationGuide())
+                  .empty());
+
+  // Add other benefit.
+  CreditCardMerchantBenefit merchant_benefit =
+      test::GetActiveCreditCardMerchantBenefit();
+  test_api(merchant_benefit)
+      .SetLinkedCardInstrumentId(
+          CreditCardBenefitBase::LinkedCardInstrumentId(card.instrument_id()));
+  test_api(merchant_benefit).SetMerchantDomains({origin});
+  payments_data_manager().AddCreditCardBenefitForTest(merchant_benefit);
+
+  EXPECT_EQ(
+      payments_data_manager().GetApplicableBenefitDescriptionForCardAndOrigin(
+          card, origin, autofill_client()->GetAutofillOptimizationGuide()),
+      merchant_benefit.benefit_description());
+}
+
+// Tests that card flat rate benefits should not be blocked if the given url is
+// on the flat rate benefit blocklist, but the blocklist feature flag is
+// disabled.
+TEST_P(PaymentsDataManagerShouldBlockBenefitsTest,
+       BlockedUrlForFlateRateBenefit_BlocklistDisabled) {
+  if (app_locale() != "en-US" && app_locale() != "en-GB") {
+    GTEST_SKIP() << "This test should not run for not supported app locale.";
+  }
+
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(
+      features::kAutofillEnableFlatRateCardBenefitsBlocklist);
+
+  const url::Origin origin =
+      url::Origin::Create(GURL("https://example-blocked-url.com/"));
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+
+  // Add flat rate benefits and linked card.
+  CreditCardFlatRateBenefit flat_rate_benefit =
+      test::GetActiveCreditCardFlatRateBenefit();
+  CreditCard card = test::GetMaskedServerCard();
+  test_api(flat_rate_benefit)
+      .SetLinkedCardInstrumentId(
+          CreditCardBenefitBase::LinkedCardInstrumentId(card.instrument_id()));
+  test_api(payments_data_manager()).AddServerCreditCard(card);
+  payments_data_manager().AddCreditCardBenefitForTest(flat_rate_benefit);
+
+  EXPECT_EQ(
+      payments_data_manager().GetApplicableBenefitDescriptionForCardAndOrigin(
+          card, origin, autofill_client()->GetAutofillOptimizationGuide()),
+      flat_rate_benefit.benefit_description());
+}
+
 INSTANTIATE_TEST_SUITE_P(
     ,
     PaymentsDataManagerShouldBlockBenefitsTest,
diff --git a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.cc b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.cc
index 71760cae..76746bf3 100644
--- a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.cc
+++ b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.cc
@@ -56,16 +56,18 @@
 }
 
 std::vector<optimization_guide::proto::OptimizationType>
-GetCardBenefitsOptimizationTypesForCard(const CreditCard& card) {
+GetCardBenefitsOptimizationTypesForCard(
+    const CreditCard& card,
+    const PaymentsDataManager& payments_data_manager) {
   std::vector<optimization_guide::proto::OptimizationType> optimization_types;
-  if (card.issuer_id() == kAmexCardIssuerId) {
+  if (card.benefit_source() == kAmexCardBenefitSource) {
     optimization_types.push_back(
         optimization_guide::proto::
             AMERICAN_EXPRESS_CREDIT_CARD_FLIGHT_BENEFITS);
     optimization_types.push_back(
         optimization_guide::proto::
             AMERICAN_EXPRESS_CREDIT_CARD_SUBSCRIPTION_BENEFITS);
-  } else if (card.issuer_id() == kBmoCardIssuerId &&
+  } else if (card.benefit_source() == kBmoCardBenefitSource &&
              base::FeatureList::IsEnabled(
                  features::
                      kAutofillEnableAllowlistForBmoCardCategoryBenefits)) {
@@ -92,14 +94,25 @@
     optimization_types.push_back(
         optimization_guide::proto::BMO_CREDIT_CARD_WHOLESALE_CLUB_BENEFITS);
   }
+  if (payments_data_manager
+          .GetFlatRateBenefitByInstrumentId(
+              CreditCardBenefitBase::LinkedCardInstrumentId(
+                  card.instrument_id()))
+          .has_value() &&
+      base::FeatureList::IsEnabled(
+          features::kAutofillEnableFlatRateCardBenefitsBlocklist)) {
+    optimization_types.push_back(
+        optimization_guide::proto::
+            SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST);
+  }
   return optimization_types;
 }
 
 void AddCreditCardOptimizationTypes(
-    base::span<const CreditCard* const> cards,
+    const PaymentsDataManager& payments_data_manager,
     base::flat_set<optimization_guide::proto::OptimizationType>&
         optimization_types) {
-  for (const CreditCard* card : cards) {
+  for (const CreditCard* card : payments_data_manager.GetServerCreditCards()) {
     auto vcn_merchant_opt_out_optimization_type =
         GetVcnMerchantOptOutOptimizationTypeForCard(*card);
     if (vcn_merchant_opt_out_optimization_type !=
@@ -114,7 +127,7 @@
     if (base::FeatureList::IsEnabled(
             features::kAutofillEnableCardBenefitsSync)) {
       auto benefits_optimization_types =
-          GetCardBenefitsOptimizationTypesForCard(*card);
+          GetCardBenefitsOptimizationTypesForCard(*card, payments_data_manager);
       if (!benefits_optimization_types.empty()) {
         optimization_types.insert(benefits_optimization_types.begin(),
                                   benefits_optimization_types.end());
@@ -213,10 +226,8 @@
         return field->Type().group() == FieldTypeGroup::kCreditCard;
       });
 
-  std::vector<const CreditCard*> server_cards;
   if (has_credit_card_field) {
-    server_cards = payments_data_manager.GetServerCreditCards();
-    AddCreditCardOptimizationTypes(server_cards, optimization_types);
+    AddCreditCardOptimizationTypes(payments_data_manager, optimization_types);
   }
 
 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \
@@ -256,18 +267,18 @@
 
 CreditCardCategoryBenefit::BenefitCategory
 AutofillOptimizationGuide::AttemptToGetEligibleCreditCardBenefitCategory(
-    std::string_view issuer_id,
+    std::string_view benefit_source,
     const GURL& url) const {
   std::vector<optimization_guide::proto::OptimizationType>
       issuer_optimization_types;
-  if (issuer_id == kAmexCardIssuerId) {
+  if (benefit_source == kAmexCardBenefitSource) {
     issuer_optimization_types.push_back(
         optimization_guide::proto::
             AMERICAN_EXPRESS_CREDIT_CARD_FLIGHT_BENEFITS);
     issuer_optimization_types.push_back(
         optimization_guide::proto::
             AMERICAN_EXPRESS_CREDIT_CARD_SUBSCRIPTION_BENEFITS);
-  } else if (issuer_id == kBmoCardIssuerId &&
+  } else if (benefit_source == kBmoCardBenefitSource &&
              base::FeatureList::IsEnabled(
                  features::
                      kAutofillEnableAllowlistForBmoCardCategoryBenefits)) {
@@ -306,7 +317,7 @@
       return GetBenefitCategoryForOptimizationType(optimization_type);
     }
   }
-  // No applicable category benefit for the 'issuer_id' on the 'url'.
+  // No applicable category benefit for the 'benefit_source' on the 'url'.
   return CreditCardCategoryBenefit::BenefitCategory::kUnknownBenefitCategory;
 }
 
@@ -377,27 +388,20 @@
   return decision == optimization_guide::OptimizationGuideDecision::kTrue;
 }
 
-bool AutofillOptimizationGuide::ShouldBlockBenefitSuggestionLabelsForCardAndUrl(
-    const CreditCard& card,
-    const GURL& url) const {
-  if (card.issuer_id() == kCapitalOneCardIssuerId) {
-    optimization_guide::OptimizationGuideDecision decision =
-        decider_->CanApplyOptimization(
-            url,
-            optimization_guide::proto::CAPITAL_ONE_CREDIT_CARD_BENEFITS_BLOCKED,
-            /*optimization_metadata=*/nullptr);
-    // Since the Capital One benefit suggestions hint uses a blocklist, it will
-    // return kFalse if the `url` is present, meaning when kFalse is returned,
-    // we should block the suggestion from being shown. If the optimization type
-    // was not registered in time before being queried, it will be kUnknown, so
-    // the default functionality in this case will be to not block the
-    // suggestion from being shown.
-    return decision == optimization_guide::OptimizationGuideDecision::kFalse;
-  }
-
-  // No conditions indicating benefits suggestions should be blocked were
-  // encountered, so return that they should not be blocked.
-  return false;
+bool AutofillOptimizationGuide::
+    ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(const GURL& url) const {
+  // Since the flat rate benefit suggestions hint uses a blocklist, it will
+  // return kFalse if the `url` is present, meaning when kFalse is returned,
+  // we should block the suggestion from being shown. If the optimization type
+  // was not registered in time before being queried, it will be kUnknown, so
+  // the default functionality in this case will be to not block the
+  // suggestion from being shown.
+  return decider_->CanApplyOptimization(
+             url,
+             optimization_guide::proto::
+                 SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST,
+             /*optimization_metadata=*/nullptr) ==
+         optimization_guide::OptimizationGuideDecision::kFalse;
 }
 
 bool AutofillOptimizationGuide::IsUrlEligibleForBnplIssuer(
diff --git a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.h b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.h
index 5a6eca6..19045194 100644
--- a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.h
+++ b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide.h
@@ -47,10 +47,10 @@
                               const PaymentsDataManager& payments_data_manager);
 
   // Checks if the `url` has an applicable category benefit for the credit card
-  // issuer `issuer_id`. If an optimization is found, returns the applicable
-  // category benefit.
+  // issuer `benefit_source`. If an optimization is found, returns the
+  // applicable category benefit.
   virtual CreditCardCategoryBenefit::BenefitCategory
-  AttemptToGetEligibleCreditCardBenefitCategory(std::string_view issuer_id,
+  AttemptToGetEligibleCreditCardBenefitCategory(std::string_view benefit_source,
                                                 const GURL& url) const;
 
   // Returns whether the URL origin contained in `url` is blocked from
@@ -72,11 +72,10 @@
   virtual bool ShouldBlockFormFieldSuggestion(const GURL& url,
                                               const CreditCard& card) const;
 
-  // Returns whether autofill benefit suggestion labels for `card` should be
-  // blocked on `url` based on the `card`'s issuer and the `url`'s presence in
-  // its corresponding blocklist.
-  virtual bool ShouldBlockBenefitSuggestionLabelsForCardAndUrl(
-      const CreditCard& card,
+  // Returns whether autofill flat rate benefit suggestion labels should be
+  // blocked on `url` based on if the `url`'s presence in its corresponding
+  // blocklist.
+  virtual bool ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(
       const GURL& url) const;
 
   // Returns whether `url` is eligible for ablation as per `type`.
diff --git a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_unittest.cc b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_unittest.cc
index 56ee4e44..2f5e8b431 100644
--- a/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_unittest.cc
+++ b/components/autofill/core/browser/integrators/optimization_guide/autofill_optimization_guide_unittest.cc
@@ -15,6 +15,7 @@
 #include "components/autofill/core/browser/data_model/payments/bnpl_issuer.h"
 #include "components/autofill/core/browser/data_model/payments/credit_card.h"
 #include "components/autofill/core/browser/data_model/payments/credit_card_benefit.h"
+#include "components/autofill/core/browser/data_model/payments/credit_card_benefit_test_api.h"
 #include "components/autofill/core/browser/data_model/payments/credit_card_test_api.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/form_structure_test_api.h"
@@ -43,6 +44,7 @@
 using test::CreateTestIbanFormData;
 using ::testing::_;
 using ::testing::Eq;
+using ::testing::IsEmpty;
 using ::testing::Matcher;
 using ::testing::Return;
 using ::testing::UnorderedElementsAre;
@@ -62,15 +64,17 @@
       std::string_view network = kVisaCard,
       CreditCard::VirtualCardEnrollmentType virtual_card_enrollment_type =
           CreditCard::VirtualCardEnrollmentType::kNetwork,
-      std::string_view issuer_id = "") {
+      std::string_view issuer_id = "",
+      std::string_view benefit_source = "") {
     CreditCard card = test::GetMaskedServerCardEnrolledIntoVirtualCardNumber();
     test_api(card).set_network_for_card(network);
     card.set_virtual_card_enrollment_type(virtual_card_enrollment_type);
     test_api(card).set_issuer_id_for_card(issuer_id);
+    card.set_benefit_source(benefit_source);
     return card;
   }
 
-  void MockCapitalOneCreditCardBenefitsBlockedDecisionForUrl(
+  void MockFlatRateCreditCardBenefitsBlockedDecisionForUrl(
       const GURL& url,
       optimization_guide::OptimizationGuideDecision decision) {
     ON_CALL(
@@ -78,7 +82,7 @@
         CanApplyOptimization(
             Eq(url),
             Eq(optimization_guide::proto::
-                   CAPITAL_ONE_CREDIT_CARD_BENEFITS_BLOCKED),
+                   SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST),
             Matcher<optimization_guide::OptimizationMetadata*>(Eq(nullptr))))
         .WillByDefault(Return(decision));
   }
@@ -412,12 +416,54 @@
   EXPECT_FALSE(guide().ShouldBlockFormFieldSuggestion(url, card));
 }
 
+// Test that we block card flat rate benefits suggestions on blocked URLs.
+TEST_F(AutofillOptimizationGuideTest,
+       ShouldBlockFlatRateBenefitSuggestionLabelsForUrl_BlockedUrl) {
+  GURL url("https://example.com/");
+
+  MockFlatRateCreditCardBenefitsBlockedDecisionForUrl(
+      url, optimization_guide::OptimizationGuideDecision::kFalse);
+
+  EXPECT_TRUE(guide().ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(url));
+}
+
+// Test that we do not block card flat rate benefits suggestions on unblocked
+// URLs.
+TEST_F(AutofillOptimizationGuideTest,
+       ShouldBlockFlatRateBenefitSuggestionLabelsForUrl_UnblockedUrl) {
+  GURL url("https://example.com/");
+
+  MockFlatRateCreditCardBenefitsBlockedDecisionForUrl(
+      url, optimization_guide::OptimizationGuideDecision::kTrue);
+
+  EXPECT_FALSE(guide().ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(url));
+}
+
+// Test that we do not block benefits suggestions when a `kUnknown` decision is
+// returned.
+TEST_F(AutofillOptimizationGuideTest,
+       ShouldBlockFlatRateBenefitSuggestionLabelsForUrl_UnknownDecision) {
+  GURL url("https://example.com/");
+  CreditCard card = GetVcnEnrolledCard(
+      kVisaCard, CreditCard::VirtualCardEnrollmentType::kNetwork,
+      kCapitalOneCardIssuerId);
+  payments_data_manager().AddServerCreditCard(card);
+
+  MockFlatRateCreditCardBenefitsBlockedDecisionForUrl(
+      url, optimization_guide::OptimizationGuideDecision::kUnknown);
+
+  EXPECT_FALSE(guide().ShouldBlockFlatRateBenefitSuggestionLabelsForUrl(url));
+}
+
 // Test that the Amex category-benefit optimization types are registered when we
 // have seen a credit card form and the user has an Amex card.
 TEST_F(AutofillOptimizationGuideTest,
        CreditCardFormFound_AmexCategoryBenefits) {
-  base::test::ScopedFeatureList feature_list{
-      features::kAutofillEnableCardBenefitsSync};
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSync,
+                            features::kAutofillEnableCardBenefitsSourceSync},
+      /*disabled_features=*/{});
   FormStructure form_structure{
       CreateTestCreditCardFormData(/*is_https=*/true,
                                    /*use_month_type=*/true)};
@@ -428,7 +474,8 @@
       /*network=*/kAmericanExpressCard,
       /*virtual_card_enrollment_type=*/
       CreditCard::VirtualCardEnrollmentType::kNetwork,
-      /*issuer_id=*/kAmexCardIssuerId));
+      /*issuer_id=*/kAmexCardIssuerId,
+      /*benefit_source=*/kAmexCardBenefitSource));
 
   EXPECT_CALL(decider(),
               RegisterOptimizationTypes(UnorderedElementsAre(
@@ -440,6 +487,103 @@
   guide().OnDidParseForm(form_structure, payments_data_manager());
 }
 
+// Test that the flat rate benefit blocklist optimization type is registered
+// when we have seen a credit card form and the user has a card with a flat rate
+// benefit.
+TEST_F(
+    AutofillOptimizationGuideTest,
+    CreditCardFormFound_FlatRateBenefitBlockList_WithFlatRateBenefit_FeatureEnabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSync,
+                            features::
+                                kAutofillEnableFlatRateCardBenefitsBlocklist},
+      /*disabled_features=*/{});
+  FormStructure form_structure{
+      CreateTestCreditCardFormData(/*is_https=*/true,
+                                   /*use_month_type=*/true)};
+  test_api(form_structure)
+      .SetFieldTypes({CREDIT_CARD_NAME_FULL, CREDIT_CARD_NUMBER,
+                      CREDIT_CARD_EXP_MONTH, CREDIT_CARD_VERIFICATION_CODE});
+  CreditCard card = test::GetMaskedServerCard();
+  payments_data_manager().AddServerCreditCard(card);
+  CreditCardFlatRateBenefit flat_rate_benefit =
+      test::GetActiveCreditCardFlatRateBenefit();
+  test_api(flat_rate_benefit)
+      .SetLinkedCardInstrumentId(
+          CreditCardBenefitBase::LinkedCardInstrumentId(card.instrument_id()));
+  payments_data_manager().AddCreditCardBenefitForTest(
+      std::move(flat_rate_benefit));
+
+  EXPECT_CALL(decider(),
+              RegisterOptimizationTypes(testing::UnorderedElementsAre(
+                  optimization_guide::proto::
+                      SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST)));
+
+  guide().OnDidParseForm(form_structure, payments_data_manager());
+}
+
+// Test that the flat rate benefit blocklist optimization type is not
+// registered when we have seen a credit card form but the user has no card
+// with a flat rate benefit.
+TEST_F(
+    AutofillOptimizationGuideTest,
+    CreditCardFormFound_FlatRateBenefitBlockList_WithoutFlatRateBenefit_FeatureEnabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSync,
+                            features::
+                                kAutofillEnableFlatRateCardBenefitsBlocklist},
+      /*disabled_features=*/{});
+  FormStructure form_structure{
+      CreateTestCreditCardFormData(/*is_https=*/true,
+                                   /*use_month_type=*/true)};
+  test_api(form_structure)
+      .SetFieldTypes({CREDIT_CARD_NAME_FULL, CREDIT_CARD_NUMBER,
+                      CREDIT_CARD_EXP_MONTH, CREDIT_CARD_VERIFICATION_CODE});
+  payments_data_manager().AddServerCreditCard(test::GetMaskedServerCard());
+
+  // The flat rate blocklist optimization type will not be registered if the
+  // no card has a flat rate benefit.
+  EXPECT_CALL(decider(), RegisterOptimizationTypes).Times(0);
+
+  guide().OnDidParseForm(form_structure, payments_data_manager());
+}
+
+// Test that the flat rate benefit blocklist optimization type is not registered
+// when we have seen a credit card form and the user has a card with flat rate
+// benefit, but the flat rate benefit blocklist flag is disabled.
+TEST_F(
+    AutofillOptimizationGuideTest,
+    CreditCardFormFound_FlatRateBenefitBlockList_WithFlatRateBenefit_FeatureDisabled) {
+  base::test::ScopedFeatureList feature_list;
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSync},
+      /*disabled_features=*/{
+          features::kAutofillEnableFlatRateCardBenefitsBlocklist});
+  FormStructure form_structure{
+      CreateTestCreditCardFormData(/*is_https=*/true,
+                                   /*use_month_type=*/true)};
+  test_api(form_structure)
+      .SetFieldTypes({CREDIT_CARD_NAME_FULL, CREDIT_CARD_NUMBER,
+                      CREDIT_CARD_EXP_MONTH, CREDIT_CARD_VERIFICATION_CODE});
+  CreditCard card = test::GetMaskedServerCard();
+  payments_data_manager().AddServerCreditCard(card);
+  CreditCardFlatRateBenefit flat_rate_benefit =
+      test::GetActiveCreditCardFlatRateBenefit();
+  test_api(flat_rate_benefit)
+      .SetLinkedCardInstrumentId(
+          CreditCardBenefitBase::LinkedCardInstrumentId(card.instrument_id()));
+  payments_data_manager().AddCreditCardBenefitForTest(
+      std::move(flat_rate_benefit));
+
+  // The flat rate blocklist optimization type will not be registered if the
+  // blocklist flag is disabled.
+  EXPECT_CALL(decider(), RegisterOptimizationTypes).Times(0);
+
+  guide().OnDidParseForm(form_structure, payments_data_manager());
+}
+
 // Test that the BMO category-benefit optimization types are registered when a
 // credit card form is present and the user has an BMO card.
 TEST_F(AutofillOptimizationGuideTest, CreditCardFormFound_BmoCategoryBenefits) {
@@ -447,7 +591,8 @@
   feature_list.InitWithFeatures(
       /*enabled_features=*/
       {features::kAutofillEnableCardBenefitsSync,
-       features::kAutofillEnableAllowlistForBmoCardCategoryBenefits},
+       features::kAutofillEnableAllowlistForBmoCardCategoryBenefits,
+       features::kAutofillEnableCardBenefitsSourceSync},
       /*disabled_features=*/{});
   FormStructure form_structure{
       CreateTestCreditCardFormData(/*is_https=*/true,
@@ -459,7 +604,8 @@
       /*network=*/kMasterCard,
       /*virtual_card_enrollment_type=*/
       CreditCard::VirtualCardEnrollmentType::kNetwork,
-      /*issuer_id=*/kBmoCardIssuerId));
+      /*issuer_id=*/kBmoCardIssuerId,
+      /*benefit_source=*/kBmoCardBenefitSource));
 
   EXPECT_CALL(
       decider(),
@@ -485,7 +631,9 @@
 TEST_F(AutofillOptimizationGuideTest,
        CreditCardFormFound_AmexCategoryBenefits_ExperimentDisabled) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndDisableFeature(features::kAutofillEnableCardBenefitsSync);
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSourceSync},
+      /*disabled_features=*/{features::kAutofillEnableCardBenefitsSync});
   FormStructure form_structure{
       CreateTestCreditCardFormData(/*is_https=*/true,
                                    /*use_month_type=*/true)};
@@ -496,7 +644,8 @@
       /*network=*/kAmericanExpressCard,
       /*virtual_card_enrollment_type=*/
       CreditCard::VirtualCardEnrollmentType::kNetwork,
-      /*issuer_id=*/kAmexCardIssuerId));
+      /*issuer_id=*/kAmexCardIssuerId,
+      /*benefit_source=*/kAmexCardBenefitSource));
 
   EXPECT_CALL(decider(),
               RegisterOptimizationTypes(UnorderedElementsAre(
@@ -515,8 +664,10 @@
 TEST_F(AutofillOptimizationGuideTest,
        CreditCardFormFound_BmoCategoryBenefits_ExperimentDisabled) {
   base::test::ScopedFeatureList feature_list;
-  feature_list.InitAndDisableFeature(
-      features::kAutofillEnableAllowlistForBmoCardCategoryBenefits);
+  feature_list.InitWithFeatures(
+      /*enabled_features=*/{features::kAutofillEnableCardBenefitsSourceSync},
+      /*disabled_features=*/{
+          features::kAutofillEnableAllowlistForBmoCardCategoryBenefits});
   FormStructure form_structure{
       CreateTestCreditCardFormData(/*is_https=*/true,
                                    /*use_month_type=*/true)};
@@ -527,7 +678,8 @@
       /*network=*/kMasterCard,
       /*virtual_card_enrollment_type=*/
       CreditCard::VirtualCardEnrollmentType::kNetwork,
-      /*issuer_id=*/kBmoCardIssuerId));
+      /*issuer_id=*/kBmoCardIssuerId,
+      /*benefit_source=*/kBmoCardBenefitSource));
 
   // Since the experiment is disabled, there should be no benefits-related
   // optimization types registered.
@@ -849,7 +1001,7 @@
 }
 
 struct BenefitOptimizationToBenefitCategoryTestCase {
-  const std::string issuer_id;
+  const std::string benefit_source;
   const optimization_guide::proto::OptimizationType optimization_type;
   const CreditCardCategoryBenefit::BenefitCategory benefit_category;
 };
@@ -860,6 +1012,7 @@
           BenefitOptimizationToBenefitCategoryTestCase> {
  public:
   BenefitOptimizationToBenefitCategoryTest() = default;
+
   ~BenefitOptimizationToBenefitCategoryTest() override = default;
 
   optimization_guide::proto::OptimizationType expected_benefit_optimization()
@@ -875,12 +1028,14 @@
   void SetUp() override {
     AutofillOptimizationGuideTest::SetUp();
     card_ = test::GetMaskedServerCard();
-    card_.set_issuer_id(GetParam().issuer_id);
+    card_.set_benefit_source(GetParam().benefit_source);
     payments_data_manager().AddServerCreditCard(card_);
   }
 
  private:
   CreditCard card_;
+  base::test::ScopedFeatureList scoped_feature_list_{
+      features::kAutofillEnableCardBenefitsSourceSync};
 };
 
 // Tests that the correct benefit category is returned when a benefit
@@ -896,7 +1051,7 @@
           Return(optimization_guide::OptimizationGuideDecision::kTrue));
 
   EXPECT_EQ(guide().AttemptToGetEligibleCreditCardBenefitCategory(
-                credit_card().issuer_id(), url),
+                credit_card().benefit_source(), url),
             expected_benefit_category());
 }
 
diff --git a/components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide.h b/components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide.h
index 39f54e8..266ec31 100644
--- a/components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide.h
+++ b/components/autofill/core/browser/integrators/optimization_guide/mock_autofill_optimization_guide.h
@@ -36,8 +36,8 @@
               (const GURL&, const CreditCard&),
               (const override));
   MOCK_METHOD(bool,
-              ShouldBlockBenefitSuggestionLabelsForCardAndUrl,
-              (const CreditCard& card, const GURL& url),
+              ShouldBlockFlatRateBenefitSuggestionLabelsForUrl,
+              (const GURL& url),
               (const override));
   MOCK_METHOD(bool,
               IsUrlEligibleForBnplIssuer,
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
index 340d9c5..a5c3312 100644
--- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -341,12 +341,18 @@
          {features::kAutofillEnableFlatRateCardBenefitsFromCurinos, true},
          {features::kAutofillEnableCardBenefitsIph, true},
          {features::kAutofillEnableNewFopDisplayDesktop, true},
+         {features::kAutofillEnableFlatRateCardBenefitsBlocklist, true},
          {features::kAutofillEnableCardBenefitsSourceSync,
           IsCreditCardBenefitsSourceSyncEnabled()}});
 
     std::u16string benefit_description;
     int64_t instrument_id;
 
+    ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+                autofill_client()->GetAutofillOptimizationGuide()),
+            ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+        .WillByDefault(testing::Return(false));
+
     if (std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
       CreditCardFlatRateBenefit benefit =
           std::get<CreditCardFlatRateBenefit>(GetBenefit());
@@ -468,6 +474,29 @@
   }
 }
 
+// Checks that for FPAN suggestions that the benefit description is displayed
+// when optimization guide is null except category benefits.
+TEST_P(AutofillCreditCardBenefitsLabelTest,
+       BenefitSuggestionLabel_Fpan_NoOptimizationGuide) {
+  autofill_client()->ResetAutofillOptimizationGuide();
+  Suggestion suggestion = CreateCreditCardSuggestionForTest(
+      card(), *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
+  ASSERT_FALSE(autofill_client()->GetAutofillOptimizationGuide());
+  if (IsCreditCardBenefitsSourceSyncEnabled() &&
+      GetBenefitSource() == "curinos" &&
+      !std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
+    EXPECT_TRUE(suggestion.labels.empty());
+  } else if (std::holds_alternative<CreditCardCategoryBenefit>(GetBenefit())) {
+    EXPECT_TRUE(suggestion.labels.empty());
+  } else {
+    EXPECT_THAT(suggestion.labels,
+                ElementsAre(std::vector<Suggestion::Text>{
+                    Suggestion::Text(expected_benefit_text())}));
+  }
+}
+
 // Checks that feature is set to display the credit card benefit IPH for
 // FPAN suggestions with benefits labels.
 TEST_P(AutofillCreditCardBenefitsLabelTest,
@@ -513,6 +542,33 @@
             nullptr);
 }
 
+// Checks that `feature` is set to null when the card is not eligible
+// for the benefits.
+TEST_P(AutofillCreditCardBenefitsLabelTest,
+       BenefitSuggestionFeatureForIph_IsNullWhenCardNotEligibleForBenefits) {
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+  Suggestion suggestion = CreateCreditCardSuggestionForTest(
+      card(), *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
+
+  if (std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
+    EXPECT_EQ(suggestion.iph_metadata.feature, nullptr);
+  } else if (IsCreditCardBenefitsSourceSyncEnabled() &&
+             GetBenefitSource() == "curinos") {
+    // Currently, Curinos only supports flat rate benefit, so when benefit
+    // source is curinos, and the benefit is not a flat rate benefit, no
+    // benefit suggestion will be shown.
+    EXPECT_EQ(suggestion.iph_metadata.feature, nullptr);
+  } else {
+    EXPECT_EQ(suggestion.iph_metadata.feature,
+              &feature_engagement::kIPHAutofillCreditCardBenefitFeature);
+  }
+}
+
 // Checks that for virtual cards suggestion the benefit description is shown
 // as a label.
 TEST_P(AutofillCreditCardBenefitsLabelTest,
@@ -614,6 +670,33 @@
   EXPECT_TRUE(suggestion.labels.empty());
 }
 
+// Checks that the benefit description is not displayed when benefit suggestions
+// are disabled for the given card and url.
+TEST_P(AutofillCreditCardBenefitsLabelTest,
+       BenefitSuggestionLabelNotDisplayed_BlockedUrl) {
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+  Suggestion suggestion = CreateCreditCardSuggestionForTest(
+      card(), *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
+
+  // Benefit description is not returned for flat rate benefits.
+  if (std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
+    EXPECT_TRUE(suggestion.labels.empty());
+  } else if ((IsCreditCardBenefitsSourceSyncEnabled() &&
+              GetBenefitSource() == "curinos")) {
+    // Currently, Curinos only supports flat rate benefit, so when benefit
+    // source is curinos, and the beneit is not a flat rate benefit, no
+    // benefit suggestion will be shown.
+    EXPECT_TRUE(suggestion.labels.empty());
+  } else {
+    EXPECT_FALSE(suggestion.labels.empty());
+  }
+}
+
 // Checks that for FPAN suggestions that the benefit description is displayed.
 TEST_P(AutofillCreditCardBenefitsLabelTest,
        BenefitSuggestionLabel_Fpan_NewFopDisplayOff) {
@@ -762,6 +845,38 @@
           CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, /*app_locale=*/"en-US"))}));
 }
 
+// Checks that the benefit description is not displayed when benefit suggestions
+// are disabled for the given card and url.
+TEST_P(AutofillCreditCardBenefitsLabelTest,
+       BenefitSuggestionLabelNotDisplayed_BlockedUrl_NewFopDisplayOff) {
+  if (!std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
+    GTEST_SKIP() << "This test should not run for non-flat-rate benefits.";
+  }
+
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndDisableFeature(
+      features::kAutofillEnableNewFopDisplayDesktop);
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+
+  Suggestion suggestion = CreateCreditCardSuggestionForTest(
+      card(), *autofill_client(), CREDIT_CARD_NUMBER,
+      /*virtual_card_option=*/false,
+      /*card_linked_offer_available=*/false);
+
+  // Benefit description is not returned for card with only flat rate benefits.
+  EXPECT_THAT(
+      CreateCreditCardSuggestionForTest(card(), *autofill_client(),
+                                        CREDIT_CARD_NUMBER,
+                                        /*virtual_card_option=*/false,
+                                        /*card_linked_offer_available=*/false)
+          .labels,
+      ElementsAre(std::vector<Suggestion::Text>{Suggestion::Text(card().GetInfo(
+          CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, /*app_locale=*/"en-US"))}));
+}
+
 #else
 
 TEST_P(AutofillCreditCardBenefitsLabelTest,
@@ -893,6 +1008,32 @@
                    .should_display_terms_available);
 }
 
+// Checks that the benefit description is not displayed when benefit suggestions
+// are disabled for the given card and url.
+TEST_P(AutofillCreditCardBenefitsLabelTest,
+       GetCreditCardSuggestionsForTouchToFill_BenefitsNotAdded_BlockedUrl) {
+  if (!std::holds_alternative<CreditCardFlatRateBenefit>(GetBenefit())) {
+    GTEST_SKIP() << "This test should not run for non-flat-rate benefits.";
+  }
+
+  ON_CALL(*static_cast<MockAutofillOptimizationGuide*>(
+              autofill_client()->GetAutofillOptimizationGuide()),
+          ShouldBlockFlatRateBenefitSuggestionLabelsForUrl)
+      .WillByDefault(testing::Return(true));
+  std::vector<CreditCard> cards = {card()};
+
+  std::vector<Suggestion> suggestions = GetCreditCardSuggestionsForTouchToFill(
+      cards, *autofill_client(), *credit_card_form_event_logger_);
+
+  // Benefit description is not returned for flat rate benefits.
+  EXPECT_THAT(suggestions[0],
+              EqualLabels({{card().GetInfo(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR,
+                                           app_locale())}}));
+  EXPECT_FALSE(suggestions[0]
+                   .GetPayload<Suggestion::PaymentsPayload>()
+                   .should_display_terms_available);
+}
+
 TEST_P(
     AutofillCreditCardBenefitsLabelTest,
     GetCreditCardSuggestionsForTouchToFill_OnMetadataLoggingContextReceivedCalled) {
diff --git a/components/optimization_guide/core/hints/hints_processing_util.cc b/components/optimization_guide/core/hints/hints_processing_util.cc
index 00f32e6..4bf477e9 100644
--- a/components/optimization_guide/core/hints/hints_processing_util.cc
+++ b/components/optimization_guide/core/hints/hints_processing_util.cc
@@ -185,6 +185,9 @@
       return "GlicPageContextEligibility";
     case proto::OptimizationType::DIGITAL_CREDENTIALS_LOW_FRICTION:
       return "DigitalCredentialsLowFriction";
+    case proto::OptimizationType::
+        SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST:
+      return "SharedCreditCardFlatRateBenefitBlocklist";
   }
 
   // The returned string is used to record histograms for the optimization type.
diff --git a/components/optimization_guide/proto/hints.proto b/components/optimization_guide/proto/hints.proto
index 97f0441..2d392af 100644
--- a/components/optimization_guide/proto/hints.proto
+++ b/components/optimization_guide/proto/hints.proto
@@ -143,7 +143,7 @@
 // enum in enums.xml and optimization/histograms.xml for metric recording.
 enum OptimizationType {
   // Values for obsolete optimizations.
-  reserved 11, 12, 16, 29, 32, 66, 72, 73, 89, 94, 95;
+  reserved 11, 12, 16, 29, 32, 66, 72, 73, 89, 94, 95, 98, 99;
 
   TYPE_UNSPECIFIED = 0;
   // This optimization blocks JavaScript on the page.
@@ -327,6 +327,8 @@
   // Provides information about whether the page is eligible for Digital
   // Credentials low friction.
   DIGITAL_CREDENTIALS_LOW_FRICTION = 97;
+  // Merchant blocklist for card flat rate benefits.
+  SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST = 100;
 }
 
 // Presents semantics for how page load URLs should be matched.
diff --git a/tools/metrics/histograms/metadata/optimization/enums.xml b/tools/metrics/histograms/metadata/optimization/enums.xml
index fb19ea5..8849fb7 100644
--- a/tools/metrics/histograms/metadata/optimization/enums.xml
+++ b/tools/metrics/histograms/metadata/optimization/enums.xml
@@ -767,6 +767,7 @@
   <int value="93" label="FEDCM_CLICKTHROUGH_RATE"/>
   <int value="96" label="GLIC_PAGE_CONTEXT_ELIGIBILITY"/>
   <int value="97" label="DIGITAL_CREDENTIALS_LOW_FRICTION"/>
+  <int value="100" label="SHARED_CREDIT_CARD_FLAT_RATE_BENEFITS_BLOCKLIST"/>
 </enum>
 
 <enum name="PageContentAnnotationsStorageStatus">
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml
index c64d709..6d3890f8 100644
--- a/tools/metrics/histograms/metadata/optimization/histograms.xml
+++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -418,6 +418,10 @@
                merchant url is eligible for entertainment credit card
                benefits. Applies to all credit cards that support benefits on
                Chrome"/>
+  <variant name="SharedCreditCardFlatRateBenefitsBlocked"
+      summary="This optimization provides information about whether a
+               merchant url is blocked from flat rate credit card benefits.
+               Applies to all credit cards that support benefits on Chrome"/>
   <variant name="SharedCreditCardFlightBenefits"
       summary="This optimization provides information about whether a
                merchant url is eligible for flight credit card benefits.