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
| Artifact | eu.purse:headless-checkout-googlepay (brings Play Services Wallet) |
| Dashboard | Google 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 |
| Manifest | Nothing. 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 |
| Keys | None in the app |
| Environment | PurseEnvironment.PRODUCTION maps to Google's production environment; every other environment, sandbox included, to Google's TEST environment |
| Google Play | Production 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
| Outcome | When |
|---|---|
Completed | The sheet was approved and /validate answered without a challenge |
ReturnedFromRedirect | A 3-D Secure step followed the sheet and the shopper came back. Not an outcome. Show a processing state; your backend confirms the payment |
Canceled | The 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.
In sandbox the sheet runs in Google's TEST environment: any Google account works, with Google's test card suite.
Troubleshooting
| Symptom | Cause |
|---|---|
| The button never appears | The device or account cannot pay (isReadyToPay answered false), or the session does not offer googlepay |
Failed with API_ERROR, message mentions no plugin_result.logs | Google Pay is offered but not configured on the gateway. Check the dashboard |
Failed with API_ERROR, message mentions not valid JSON | The 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_IMPLEMENTED | The -googlepay artifact is missing. See Payment methods |