Skip to main content

Google Pay

Google Pay is self-submitting: its branded button is the Pay button. The tap opens Google's payment sheet, the approval selects the method as primary and runs /validate.

Setup​

Artifacteu.purse:headless-checkout-googlepay (brings Play Services Wallet)
DashboardGoogle Pay activated on the entity with a gateway (Ingenico/Worldline, Adyen or another partner). The gateway merchant id and merchant name are configured there and reach the app through /init
ManifestNothing. The com.google.android.gms.wallet.api.enabled meta-data Google requires ships in the artifact; the 3-D Secure return uses the SDK's Activity
KeysNone in the app
EnvironmentPurseEnvironment.PRODUCTION maps to Google's production environment; every other environment, sandbox included, to Google's TEST environment
Google PlayProduction requires your app to be approved by Google for Google Pay, as for any integration (Google's checklist)
// app/build.gradle.kts
dependencies {
implementation("eu.purse:headless-checkout-googlepay:${SDK_VERSION}")
}

Render​

Render the element as soon as the method is listed. Its button shows itself once Google confirms the device can pay. Never call setPrimary for it, and never place a Pay button of yours next to it.

val element = rememberPaymentElement(checkout, googlePayMethod, listener)
PaymentElementUi(element, Modifier.fillMaxWidth().height(56.dp)) // the branded button is the submit

element.ready turns true when isReadyToPay resolved. hasUi is true, selfSubmitting is true.

Creating the element runs POST /init to fetch the gateway configuration. With Ingenico/Worldline the SDK also asks Worldline for the supported card networks; if that lookup fails the sheet falls back to Visa and Mastercard and payment still works.

Outcomes​

OutcomeWhen
CompletedThe sheet was approved and /validate answered without a challenge
ReturnedFromRedirectA 3-D Secure step followed the sheet and the shopper came back. Not an outcome. Show a processing state; your backend confirms the payment
CanceledThe shopper dismissed the sheet. The split is untouched
Failed/init failed, the sheet failed, or /validate threw

A Failed from /init means the button never showed: the method is disabled with PARTNER_UI_FATAL_ERROR, nothing was charged. Leave the shopper able to pick another method.

Two sheets, one session​

A double tap is ignored while a sheet or a /validate is in flight: a second /validate for one session is refused by the API. Hide the button, or leave the screen, once the payment is done.

Testing

In sandbox the sheet runs in Google's TEST environment: any Google account works, with Google's test card suite.

Troubleshooting​

SymptomCause
The button never appearsThe device or account cannot pay (isReadyToPay answered false), or the session does not offer googlepay
Failed with API_ERROR, message mentions no plugin_result.logsGoogle Pay is offered but not configured on the gateway. Check the dashboard
Failed with API_ERROR, message mentions not valid JSONThe gateway returned an unexpected configuration. Contact Purse support with the session id
The method is listed but has no UI, submit() fails with METHOD_NOT_IMPLEMENTEDThe -googlepay artifact is missing. See Payment methods