@@ -26,6 +26,7 @@ import android.net.Uri
2626import android.os.Looper
2727import androidx.core.net.toUri
2828import com.shopify.checkoutkit.ShopifyCheckoutKit.log
29+ import kotlinx.serialization.SerialName
2930import kotlinx.serialization.Serializable
3031import kotlinx.serialization.json.Json
3132import kotlinx.serialization.json.JsonElement
@@ -67,14 +68,14 @@ public object CheckoutProtocol {
6768 public val lineItemsChange: NotificationDescriptor <Checkout > = checkoutDescriptor(" ec.line_items.change" )
6869 internal val buyerChange: NotificationDescriptor <Checkout > = checkoutDescriptor(" ec.buyer.change" )
6970 public val totalsChange: NotificationDescriptor <Checkout > = checkoutDescriptor(" ec.totals.change" )
70- public val error: NotificationDescriptor <CheckoutError > = NotificationDescriptor (
71+ public val error: NotificationDescriptor <CheckoutErrorResponse > = NotificationDescriptor (
7172 method = " ec.error" ,
7273 decode = { params ->
73- params?.jsonObject?.get( " messages " )?. let {
74+ params?.let {
7475 try {
75- json.decodeFromJsonElement<List < CheckoutError >> (it).firstOrNull( )
76+ json.decodeFromJsonElement<CheckoutErrorResponse > (it)
7677 } catch (e: Exception ) {
77- log.d(BaseWebView .ECP_LOG_TAG , " Failed to decode ec.error messages : $e raw=$it " )
78+ log.d(BaseWebView .ECP_LOG_TAG , " Failed to decode ec.error params : $e raw=$it " )
7879 null
7980 }
8081 }
@@ -320,7 +321,20 @@ internal sealed class WindowOpenResult {
320321 data class Rejected (val reason : String? = null ) : WindowOpenResult()
321322}
322323
323- /* * Payload delivered with the [CheckoutProtocol.error] notification. */
324+ /* *
325+ * Payload delivered with the [CheckoutProtocol.error] notification.
326+ *
327+ * Mirrors the UCP `ec.error` params shape — a session-fatal envelope carrying the full
328+ * list of error [messages] (consumers should iterate, not assume a single message) and
329+ * an optional [continueUrl] for buyer handoff or session recovery.
330+ */
331+ @Serializable
332+ public data class CheckoutErrorResponse internal constructor(
333+ public val messages : List <CheckoutError > = emptyList(),
334+ @SerialName(" continue_url" ) public val continueUrl : String? = null ,
335+ )
336+
337+ /* * A single error message inside a [CheckoutErrorResponse]. */
324338@Serializable
325339public data class CheckoutError internal constructor(
326340 public val code : String? = null ,
0 commit comments