diff --git a/Example/PaymentSheet Example/PaymentSheetUITest/EmbeddedUITest.swift b/Example/PaymentSheet Example/PaymentSheetUITest/EmbeddedUITest.swift
index 42ff4d461db..1e482dd3ad0 100644
--- a/Example/PaymentSheet Example/PaymentSheetUITest/EmbeddedUITest.swift	
+++ b/Example/PaymentSheet Example/PaymentSheetUITest/EmbeddedUITest.swift	
@@ -73,7 +73,7 @@ class EmbeddedUITests: PaymentSheetUITestCase {
         let aliPayAnalytics = analyticsLog.compactMap({ $0[string: "event"] })
         XCTAssertEqual(
             aliPayAnalytics,
-            ["mc_load_started", "link.account_lookup.complete", "mc_load_succeeded", "mc_carousel_payment_method_tapped"]
+            ["mc_embedded_update_started", "mc_load_started", "link.account_lookup.complete", "mc_load_succeeded", "mc_embedded_update_finished", "mc_carousel_payment_method_tapped"]
         )
 
         // ...and *updating* to a SetupIntent...
@@ -122,9 +122,7 @@ class EmbeddedUITests: PaymentSheetUITestCase {
         let klarnaAnalytics = analyticsLog.compactMap({ $0[string: "event"] })
         XCTAssertEqual(
             klarnaAnalytics,
-            ["mc_load_started", "link.account_lookup.complete", "mc_load_succeeded", "mc_carousel_payment_method_tapped",
-             "mc_form_shown", "mc_form_completed", "mc_confirm_button_tapped",
-            ]
+            ["mc_embedded_update_started", "mc_load_started", "link.account_lookup.complete", "mc_load_succeeded", "mc_embedded_update_finished", "mc_carousel_payment_method_tapped", "mc_form_shown", "mc_form_completed", "mc_confirm_button_tapped"]
         )
 
         // ...switching back to payment should keep Klarna selected
diff --git a/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift b/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift
index baf099dddc3..b0e786d581d 100644
--- a/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift
+++ b/StripeCore/StripeCore/Source/Analytics/STPAnalyticEvent.swift
@@ -77,7 +77,14 @@ import Foundation
 
     // MARK: - Embedded Payment Element init
     case mcInitEmbedded = "mc_embedded_init"
-
+    
+    // MARK: - Embedded Payment Element confirm
+    case mcConfirmEmbedded = "mc_embedded_confirm"
+    
+    // MARK: - Embedded Payment Element update
+    case mcUpdateStartedEmbedded = "mc_embedded_update_started"
+    case mcUpdateFinishedEmbedded = "mc_embedded_update_finished"
+    
     // MARK: - PaymentSheet Show
     case mcShowCustomNewPM = "mc_custom_sheet_newpm_show"
     case mcShowCustomSavedPM = "mc_custom_sheet_savedpm_show"
diff --git a/StripePaymentSheet/StripePaymentSheet/Source/Analytics/PaymentSheetAnalyticsHelper.swift b/StripePaymentSheet/StripePaymentSheet/Source/Analytics/PaymentSheetAnalyticsHelper.swift
index 295d26a74ca..c227ab83ad5 100644
--- a/StripePaymentSheet/StripePaymentSheet/Source/Analytics/PaymentSheetAnalyticsHelper.swift
+++ b/StripePaymentSheet/StripePaymentSheet/Source/Analytics/PaymentSheetAnalyticsHelper.swift
@@ -24,6 +24,17 @@ final class PaymentSheetAnalyticsHelper {
         case flowController
         case complete
         case embedded
+        
+        var analyticsValue: String {
+            switch self {
+            case .flowController:
+                return "flowcontroller"
+            case .complete:
+                return "paymentsheet"
+            case .embedded:
+                return "embedded"
+            }
+        }
     }
 
     init(
@@ -70,7 +81,7 @@ final class PaymentSheetAnalyticsHelper {
 
     func logLoadStarted() {
         loadingStartDate = Date()
-        log(event: .paymentSheetLoadStarted)
+        log(event: .paymentSheetLoadStarted, params: ["integration_shape": integrationShape.analyticsValue])
     }
 
     func logLoadFailed(error: Error) {
@@ -82,7 +93,8 @@ final class PaymentSheetAnalyticsHelper {
         log(
             event: .paymentSheetLoadFailed,
             duration: duration,
-            error: error
+            error: error,
+            params: ["integration_shape": integrationShape.analyticsValue]
         )
     }
 
@@ -114,6 +126,7 @@ final class PaymentSheetAnalyticsHelper {
             "selected_lpm": defaultPaymentMethodAnalyticsValue,
             "intent_type": intent.analyticsValue,
             "ordered_lpms": orderedPaymentMethodTypes.map({ $0.identifier }).joined(separator: ","),
+            "integration_shape": integrationShape.analyticsValue
         ]
         let linkEnabled: Bool = PaymentSheet.isLinkEnabled(elementsSession: elementsSession, configuration: configuration)
         if linkEnabled {
@@ -124,6 +137,7 @@ final class PaymentSheetAnalyticsHelper {
             guard let loadingStartDate else { return 0 }
             return Date().timeIntervalSince(loadingStartDate)
         }()
+
         log(
             event: .paymentSheetLoadSucceeded,
             duration: duration,
@@ -320,6 +334,25 @@ final class PaymentSheetAnalyticsHelper {
             linkUI: paymentOption.linkUIAnalyticsValue
         )
     }
+    
+    func logEmbeddedUpdateStarted() {
+        stpAssert(integrationShape == .embedded, "This function should only be used with embedded integration")
+        log(event: .mcUpdateStartedEmbedded)
+    }
+
+    func logEmbeddedUpdateFinished(result: EmbeddedPaymentElement.UpdateResult, duration: TimeInterval) {
+        stpAssert(integrationShape == .embedded, "This function should only be used with embedded integration")
+        
+        let error: Error? = {
+            switch result {
+            case .failed(let error):
+                return error
+            default:
+                return nil
+            }
+        }()
+        log(event: .mcUpdateFinishedEmbedded, duration: duration, error: error, params: ["status": result.analyticValue])
+    }
 
     func log(
         event: STPAnalyticEvent,
@@ -431,3 +464,16 @@ extension PaymentElementConfiguration {
         return payload
     }
 }
+
+extension EmbeddedPaymentElement.UpdateResult {
+    var analyticValue: String {
+        switch self {
+        case .succeeded:
+            return "succeeded"
+        case .canceled:
+            return "canceled"
+        case .failed(_):
+            return "failed"
+        }
+    }
+}
diff --git a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElement.swift b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElement.swift
index 9e5b34fa8e1..ac7b8f293e7 100644
--- a/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElement.swift
+++ b/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElement.swift
@@ -104,9 +104,13 @@ public final class EmbeddedPaymentElement {
     public func update(
         intentConfiguration: IntentConfiguration
     ) async -> UpdateResult {
+        let startTime = Date()
+        analyticsHelper.logEmbeddedUpdateStarted()
         // Do not process any update calls if we have already successfully confirmed an intent
         guard !hasConfirmedIntent else {
-            return .failed(error: PaymentSheetError.embeddedPaymentElementAlreadyConfirmedIntent)
+            let result: EmbeddedPaymentElement.UpdateResult = .failed(error: PaymentSheetError.embeddedPaymentElementAlreadyConfirmedIntent)
+            analyticsHelper.logEmbeddedUpdateFinished(result: result, duration: Date().timeIntervalSince(startTime))
+            return result
         }
 
         embeddedPaymentMethodsView.isUserInteractionEnabled = false
@@ -184,6 +188,7 @@ public final class EmbeddedPaymentElement {
         self.latestUpdateTask = currentUpdateTask
         let updateResult = await currentUpdateTask.value
         embeddedPaymentMethodsView.isUserInteractionEnabled = true
+        analyticsHelper.logEmbeddedUpdateFinished(result: updateResult, duration: Date().timeIntervalSince(startTime))
         return updateResult
     }
 
@@ -192,6 +197,7 @@ public final class EmbeddedPaymentElement {
     /// - Note: This method presents authentication screens on the instance's  `presentingViewController` property.
     /// - Note: This method requires that the last call to `update` succeeded. If the last `update` call failed, this call will fail. If this method is called while a call to `update` is in progress, it waits until the `update` call completes.
     public func confirm() async -> EmbeddedPaymentElementResult {
+        analyticsHelper.log(event: .mcConfirmEmbedded)
         guard let presentingViewController else {
             let errorMessage = "Presenting view controller is nil. Please set EmbeddedPaymentElement.presentingViewController."
             stpAssertionFailure(errorMessage)
diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/EmbeddedPaymentElementTest.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/EmbeddedPaymentElementTest.swift
index c3584474b0c..293de0e41cb 100644
--- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/EmbeddedPaymentElementTest.swift
+++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/EmbeddedPaymentElementTest.swift
@@ -93,8 +93,8 @@ class EmbeddedPaymentElementTest: XCTestCase {
 
             // Sanity check that the analytics...
             let analytics = STPAnalyticsClient.sharedClient._testLogHistory
-            let loadStartedEvents = analytics.filter { $0["event"] as? String == "mc_load_started" }
-            let loadSucceededEvents = analytics.filter { $0["event"] as? String == "mc_load_succeeded" }
+            let loadStartedEvents = analytics.filter { $0["event"] as? String == "mc_load_started" && $0["integration_shape"] as? String == "embedded" }
+            let loadSucceededEvents = analytics.filter { $0["event"] as? String == "mc_load_succeeded" && $0["integration_shape"] as? String == "embedded" }
             // ...have the expected # of start and succeeded events...
             XCTAssertEqual(loadStartedEvents.count, 3)
             XCTAssertEqual(loadSucceededEvents.count, 3)
@@ -257,6 +257,12 @@ class EmbeddedPaymentElementTest: XCTestCase {
         case .canceled:
             XCTFail("Expected confirm to succeed, but it was canceled")
         }
+        
+        // Check our confirm analytics
+        let analytics = STPAnalyticsClient.sharedClient._testLogHistory
+        let confirmEvents = analytics.filter { $0["event"] as? String == "mc_embedded_confirm" }
+        // ...have the expected # of confirm events...
+        XCTAssertEqual(confirmEvents.count, 1)
     }
 
     func testConfirmWithInvalidCard() async throws {
diff --git a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetAnalyticsHelperTest.swift b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetAnalyticsHelperTest.swift
index 80154cbfe57..b2df51d34f5 100644
--- a/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetAnalyticsHelperTest.swift
+++ b/StripePaymentSheet/StripePaymentSheetTests/PaymentSheet/PaymentSheetAnalyticsHelperTest.swift
@@ -112,33 +112,63 @@ final class PaymentSheetAnalyticsHelperTest: XCTestCase {
     }
 
     func testLogLoadFailed() {
-        let sut = PaymentSheetAnalyticsHelper(integrationShape: .complete, configuration: PaymentSheet.Configuration(), analyticsClient: analyticsClient)
-        // Load started -> failed
-        sut.logLoadStarted()
-        sut.logLoadFailed(error: NSError(domain: "domain", code: 1))
-        XCTAssertEqual(analyticsClient._testLogHistory[0]["event"] as? String, "mc_load_started")
-        XCTAssertEqual(analyticsClient._testLogHistory[1]["event"] as? String, "mc_load_failed")
-        XCTAssertLessThan(analyticsClient._testLogHistory[1]["duration"] as! Double, 1.0)
+        let integrationShapes: [(PaymentSheetAnalyticsHelper.IntegrationShape, String)] = [
+            (.complete, "paymentsheet"),
+            (.embedded, "embedded"),
+            (.flowController, "flowcontroller")
+        ]
+        
+        for (shape, shapeString) in integrationShapes {
+            let sut = PaymentSheetAnalyticsHelper(integrationShape: shape, configuration: PaymentSheet.Configuration(), analyticsClient: analyticsClient)
+            
+            // Reset the analytics client for each iteration
+            analyticsClient._testLogHistory.removeAll()
+            
+            // Load started -> failed
+            sut.logLoadStarted()
+            sut.logLoadFailed(error: NSError(domain: "domain", code: 1))
+            
+            XCTAssertEqual(analyticsClient._testLogHistory[0]["event"] as? String, "mc_load_started")
+            XCTAssertEqual(analyticsClient._testLogHistory[0]["integration_shape"] as? String, shapeString)
+            XCTAssertEqual(analyticsClient._testLogHistory[1]["event"] as? String, "mc_load_failed")
+            XCTAssertLessThan(analyticsClient._testLogHistory[1]["duration"] as! Double, 1.0)
+            XCTAssertEqual(analyticsClient._testLogHistory[1]["integration_shape"] as? String, shapeString)
+        }
     }
 
     func testLogLoadSucceeded() {
-        let sut = PaymentSheetAnalyticsHelper(integrationShape: .complete, configuration: PaymentSheet.Configuration(), analyticsClient: analyticsClient)
-        // Load started -> succeeded
-        sut.logLoadStarted()
-        sut.logLoadSucceeded(
-            intent: ._testValue(),
-            elementsSession: ._testCardValue(),
-            defaultPaymentMethod: .applePay,
-            orderedPaymentMethodTypes: [.stripe(.card), .external(._testPayPalValue())]
-        )
-        XCTAssertEqual(analyticsClient._testLogHistory[0]["event"] as? String, "mc_load_started")
-
-        let loadSucceededPayload = analyticsClient._testLogHistory[1]
-        XCTAssertEqual(loadSucceededPayload["event"] as? String, "mc_load_succeeded")
-        XCTAssertLessThan(loadSucceededPayload["duration"] as! Double, 1.0)
-        XCTAssertEqual(loadSucceededPayload["selected_lpm"] as? String, "apple_pay")
-        XCTAssertEqual(loadSucceededPayload["intent_type"] as? String, "payment_intent")
-        XCTAssertEqual(loadSucceededPayload["ordered_lpms"] as? String, "card,external_paypal")
+        let integrationShapes: [(PaymentSheetAnalyticsHelper.IntegrationShape, String)] = [
+            (.complete, "paymentsheet"),
+            (.embedded, "embedded"),
+            (.flowController, "flowcontroller")
+        ]
+        
+        for (shape, shapeString) in integrationShapes {
+            let sut = PaymentSheetAnalyticsHelper(integrationShape: shape, configuration: PaymentSheet.Configuration(), analyticsClient: analyticsClient)
+            
+            // Reset the analytics client for each iteration
+            analyticsClient._testLogHistory.removeAll()
+            
+            // Load started -> succeeded
+            sut.logLoadStarted()
+            sut.logLoadSucceeded(
+                intent: ._testValue(),
+                elementsSession: ._testCardValue(),
+                defaultPaymentMethod: .applePay,
+                orderedPaymentMethodTypes: [.stripe(.card), .external(._testPayPalValue())]
+            )
+            
+            XCTAssertEqual(analyticsClient._testLogHistory[0]["event"] as? String, "mc_load_started")
+            XCTAssertEqual(analyticsClient._testLogHistory[0]["integration_shape"] as? String, shapeString)
+            
+            let loadSucceededPayload = analyticsClient._testLogHistory[1]
+            XCTAssertEqual(loadSucceededPayload["event"] as? String, "mc_load_succeeded")
+            XCTAssertLessThan(loadSucceededPayload["duration"] as! Double, 1.0)
+            XCTAssertEqual(loadSucceededPayload["selected_lpm"] as? String, "apple_pay")
+            XCTAssertEqual(loadSucceededPayload["intent_type"] as? String, "payment_intent")
+            XCTAssertEqual(loadSucceededPayload["ordered_lpms"] as? String, "card,external_paypal")
+            XCTAssertEqual(loadSucceededPayload["integration_shape"] as? String, shapeString)
+        }
     }
 
     func testLogShow() {
@@ -369,6 +399,42 @@ final class PaymentSheetAnalyticsHelperTest: XCTestCase {
         )
         XCTAssertEqual(analyticsClient._testLogHistory.last!["link_context"] as? String, "link_card_brand")
     }
+    
+    func testLogEmbeddedUpdate() {
+        let sut = PaymentSheetAnalyticsHelper(integrationShape: .embedded, configuration: PaymentSheet.Configuration(), analyticsClient: analyticsClient)
+        let testDuration: TimeInterval = 10.5
+        
+        // Test update started
+        sut.logEmbeddedUpdateStarted()
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["event"] as? String, "mc_embedded_update_started")
+        
+        // Test successful update
+        sut.logEmbeddedUpdateFinished(result: .succeeded, duration: testDuration)
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["event"] as? String, "mc_embedded_update_finished")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["status"] as? String, "succeeded")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["duration"] as? TimeInterval, testDuration)
+        XCTAssertNil(analyticsClient._testLogHistory.last!["error_type"])
+        XCTAssertNil(analyticsClient._testLogHistory.last!["error_code"])
+        
+        // Test failed update
+        sut.logEmbeddedUpdateStarted()
+        let error = NSError(domain: "test", code: 123)
+        sut.logEmbeddedUpdateFinished(result: .failed(error: error), duration: testDuration)
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["event"] as? String, "mc_embedded_update_finished")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["status"] as? String, "failed")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["duration"] as? TimeInterval, testDuration)
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["error_type"] as? String, "test")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["error_code"] as? String, "123")
+        
+        // Test canceled update
+        sut.logEmbeddedUpdateStarted()
+        sut.logEmbeddedUpdateFinished(result: .canceled, duration: testDuration)
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["event"] as? String, "mc_embedded_update_finished")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["status"] as? String, "canceled")
+        XCTAssertEqual(analyticsClient._testLogHistory.last!["duration"] as? TimeInterval, testDuration)
+        XCTAssertNil(analyticsClient._testLogHistory.last!["error_type"])
+        XCTAssertNil(analyticsClient._testLogHistory.last!["error_code"])
+    }
 
     // MARK: - Helpers