Add ECP support to Android Checkout Kit#21
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
d62d273 to
ffd83a8
Compare
| } | ||
| } | ||
|
|
||
| sealed class SDKOperation(val key: String) { |
There was a problem hiding this comment.
oh yeah, we'll need to figure out preloading r.e. presented.
Unless we don't support preload initially.
We did say Page Visibility API was likely the way to go if browser support is good enough
(this was for delaying client side checkout_started, and emission of web pixel events)
|
|
||
| private fun handleReady(request: EcpRequest) { | ||
| log.d(LOG_TAG, "Handling $METHOD_READY, sending ACK.") | ||
| sendResult(request.id, "{}") |
There was a problem hiding this comment.
shall we make the empty thing a constant so we can name it to try for a bit of documentation
ffd83a8 to
dee7e16
Compare
04ed7d5 to
b07b867
Compare
d9b961e to
e8a916e
Compare
b07b867 to
745fbbd
Compare
e8a916e to
9bd2cbe
Compare
f7708b8 to
ed6b26f
Compare
5ccb8a9 to
2ccc8fb
Compare
d9e4494 to
69fb61c
Compare
|
🚀 |
69fb61c to
8f1a93f
Compare
8f1a93f to
56f8d35
Compare
kieran-osgood-shopify
left a comment
There was a problem hiding this comment.
I think we are removing the apollo codegen by mistake for the swift dev.yml
kieran-osgood-shopify
left a comment
There was a problem hiding this comment.
Ignore previous review, didn't see the new dev.yml
| name: checkout-kit | ||
|
|
||
| commands: | ||
| codegen: |
There was a problem hiding this comment.
Just a thought we had, it'd be nice if the default behaviour was to just generate for all platforms (dev codegen)building kotlin swift and typescript (just types, no schemas)
maybe as we have apollo codegen, it would be dev protocol codegen / dev protocol generate so its namespaced to the package area?
There was a problem hiding this comment.
can we do it as a follow up since I don't have the swift code in this branch?

What changes are you making?
Adds Embedded Checkout Protocol (ECP) support to the Android library and removes the legacy
MobileCheckoutSdkbridge.Embedded Checkout Protocol
A new
EmbeddedCheckoutProtocolConsumerJS interface is registered on everyCheckoutWebView. The checkout page callswindow.EmbeddedCheckoutProtocolConsumer.postMessage(jsonRpcString)to send JSON-RPC 2.0 messages to native; the SDK responds viawindow.EmbeddedCheckoutProtocol.postMessage(responseString).Full handling per the UCP embedded spec:
ec.ready{"result":{"ucp":{"version":"…","status":"success"}}}then notifies typed clientec.auth-32601) — SDK does not support identity linkingec.payment.instruments_change_request-32601) — not yet supportedec.payment.credential_request-32601) — not yet supportedec.fulfillment.address_change_request-32601) — not yet supportedec.window.open_requestCheckoutCommunicationClient.openExternalUrl(url)if registered; falls back toCheckoutEventProcessor.onCheckoutLinkClicked(url)(default browser/app routing) if not. Always responds with{"result":{"ucp":{"version":"…","status":"success"}}}for valid http/https URLsec.startclient.process()ec.errorclient.process()ec.completeclient.process()ec.*.changeclient.process()ep.*methodsclient.process(); non-null response forwarded back to checkoutMobileCheckoutSdkbridge removedThe old native→JS send path (
window.MobileCheckoutSdk.dispatchMessage(…)) has been removed entirely:CheckoutBridge.sendMessage(),SDKOperation, anddispatchMessageTemplate()are gone.SdkToWebEvent,InstrumentationPayload, andInstrumentationTypeare gone.presentedhandshake (sent after both page load and dialog show) is superseded by theec.readyhandshake.checkout_finished_loadinginstrumentation message is no longer sent.CheckoutWebView.notifyPresented()removed; thesetOnShowListenerinCheckoutDialogno longer calls it.The JS→native receive path (
window.android.postMessage(…)handlingcompleted,error,webPixels,checkoutBlockingEvent) is unchanged.User-agent simplification
BaseWebView.userAgentSuffix()now emits justShopifyCheckoutKit/<version> android [platform]instead of the previousShopifyCheckoutSDK/<version> (<cspSchema>;<theme>;<variant>) [platform]string.Typed ECP client (
CheckoutProtocol)A new
CheckoutProtocolobject provides a fluent, type-safe way to subscribe to EC notifications:Clientimplements value semantics — each.on()call returns a new instance, making it safe to share a base configuration across multiple presents. Handlers are always invoked on the main thread.Predefined descriptors:
start,complete,messagesChange,lineItemsChange,buyerChange,paymentChange,ready.UCP type generation
Models.ktis generated from vendored UCP JSON Schemas via the sharedscripts/generate_models.shscript at the repo root:The script accepts
--lang kotlinor--lang swift, producing@Serializabledata classes for Android or Codable structs for Swift respectively. It usesquicktype --framework kotlinxand applies sed post-processing to satisfy-Xexplicit-api=strict(quicktype Kotlin has no--access-levelflag). Type schemas live inucp/schemas/shopping/at the repo root; result schemas for request/response pairs are extracted fromucp/services/shopping/embedded.openrpc.jsonviajq.New public API
CheckoutCommunicationClientinterface:fun process(message: String): String?— receives all delegated EC messages; return a JSON-RPC response string ornull.fun openExternalUrl(url: Uri): Boolean— called forec.window.open_request; returntrueif the URL was displayed externally.ShopifyCheckoutKit.present(…, communicationClient: CheckoutCommunicationClient? = null)— optional fourth parameter, backward-compatible (@JvmOverloads).CheckoutProtocol— typed client entry point (see above).NotificationDescriptor<P>— descriptor type for binding typed handlers.ReadyPayload— payload forCheckoutProtocol.ready, carriesdelegations: List<String>.Checkout,CheckoutLineItem,BuyerClass, etc.) generated intoModels.kt.Files changed
CheckoutBridge.kt— removed send-side; receive-side unchangedCheckoutWebView.kt— removedpresented/loadCompletedispatch,notifyPresented(),initLoadTime, instrumentation send; registersEmbeddedCheckoutProtocolBaseWebView.kt— simplified user-agent suffix; removedabstract val variantandabstract val cspSchemaFallbackWebView.kt— removedvariantandcspSchemaoverridesCheckoutDialog.kt— removedsetOnShowListener/notifyPresented()call; threadscommunicationClientShopifyCheckoutKit.kt— adds optionalcommunicationClienttopresent()CheckoutCommunicationClient.kt— new public interfaceEmbeddedCheckoutProtocol.kt— new internal JS bridge handler +EcpRequestdata classCheckoutProtocol.kt— new typed client (Client,NotificationDescriptor,ReadyPayload)Models.kt— generated UCP Kotlin types (do not edit directly; regenerate viadev codegen kotlin)scripts/generate_models.sh— shared type generation script (repo root); supports--lang kotlinand--lang swiftucp/— vendored UCP JSON Schemas and OpenRPC service spec (repo root, shared across platforms)lib/api/lib.api— updated baselineHow to test
Run the test suite:
Verify the public API surface:
Build the sample app:
cd android/samples/MobileBuyIntegration ./gradlew assembleDebugIntegration smoke test — in a host app:
ec.readyis acknowledged andCheckoutProtocol.readyhandler firesec.startshows the progress bar and firesCheckoutProtocol.starthandlerec.payment.instruments_change_requestreceives a-32601error response (not a hang)ec.window.open_requestwith noonOpenExternalUrlhandler opens the URL viaDefaultCheckoutEventProcessor(system browser) and sends the UCP success resultec.window.open_requestwith a registered handler calls it and sends the UCP success result ontrue, falls back to event processor onfalseclient.process()with the raw JSON-RPC stringJava interop — the three-argument overload without
communicationClientmust still compile from Java:Before you merge
Important
android/README.md)Releasing a new Android version?
versionNameinandroid/lib/build.gradleandroid/CHANGELOG.mdandroid/README.mdTip
See the Contributing documentation for the full release process per platform.