Enhancing Android Checkout with Dynamic Callbacks in Google Pay

Published: (June 1, 2026 at 08:17 PM EDT)
4 min read

Source: Google Developers Blog

May 26, 2026

We are excited to bring Express Checkout with Google Pay for Android native apps, enabling developers to leverage users’ stored credentials (payment and address) from Google Wallet to streamline their checkout journeys. You will be able to implement the familiar callbacks onPaymentDataChanged and onPaymentAuthorized—already supported on the Web—in your Android applications and streamline the checkout funnels.

With these callbacks you can:

  • Update shipping options, taxes, and total prices dynamically as users interact with the Google Pay sheet.
  • Handle authorization feedback without ever closing the sheet.

This feature is available with play-services-wallet:20.0.0 and later.


Why use Dynamic Callbacks?

Dynamic callbacks enable a true Express Checkout experience. By moving the Google Pay button upstream to your Product Detail or Cart pages, you can provide the user’s shipping address, payment credentials, and contact details—all within the Pay sheet.

  • Dynamic Shipping & Taxes – Update shipping methods and calculate tax on‑the‑fly based on the user’s selected address.
  • Upstream Positioning – Place the Pay button earlier in the funnel to drive higher conversion rates.
  • Inline Authorization – Handle transaction authorization and retries directly within the Google Pay interface.

Getting Started

  1. Update the Google Pay dependency in your build.gradle file:

    implementation "com.google.android.gms:play-services-wallet:20.0.0"
  2. Implement the callback logic.

    import com.google.android.gms.wallet.PaymentData
    import com.google.android.gms.wallet.callback.BasePaymentDataCallbacks
    import com.google.android.gms.wallet.callback.IntermediatePaymentData
    import com.google.android.gms.wallet.callback.OnCompleteListener
    import com.google.android.gms.wallet.callback.PaymentAuthorizationResult
    import com.google.android.gms.wallet.callback.PaymentDataRequestUpdate
    import org.json.JSONObject
    
    class MerchantPaymentDataCallbacks : BasePaymentDataCallbacks() {
    
        /**
         * Handles payment data changes in the payment sheet such as shipping address
         * and shipping options.
         */
        override fun onPaymentDataChanged(
            request: IntermediatePaymentData,
            onCompleteListener: OnCompleteListener
        ) {
            // Example: Process the request and return updates.
            // In a real app you would likely make a network request to your server
            // to get updated shipping options and cart details based on the new address.
    
            val shippingAddress = request.shippingAddress
            val shippingOptionData = request.shippingOptionData
    
            // Construct the response object.
            val responseJson = JSONObject().apply {
                // New shipping options based on the address.
                put("newShippingOptionParameters", JSONObject().apply {
                    put("defaultSelectedOptionId", "shipping-001")
                    put("shippingOptions", JSONObject().apply {
                        put("id", "shipping-001")
                        put("label", "$0.00: Free shipping")
                        put("description", "Free shipping on all orders")
                    })
                })
    
                // Updated transaction info.
                put("newTransactionInfo", JSONObject().apply {
                    put("totalPriceStatus", "FINAL")
                    put("totalPrice", "12.34")
                    put("currencyCode", "USD")
                })
            }
    
            val response = PaymentDataRequestUpdate.fromJson(responseJson.toString())
            onCompleteListener.complete(response)
        }
    
        /**
         * Called when a payment is authorized in the payment sheet.
         */
        override fun onPaymentAuthorized(
            request: PaymentData,
            onCompleteListener: OnCompleteListener
        ) {
            // Log the payment data for debugging.
            println("onPaymentAuthorized called with PaymentData: ${request.toJson()}")
    
            // Example: Process the payment authorization.
            // In a real app you would send the payment token and other data
            // to your server to be processed by your payment service provider.
    
            // Construct the response object.
            val responseJson = JSONObject().apply {
                put("transactionState", "SUCCESS") // Or "ERROR"
                // Optionally include an error message:
                // put("error", JSONObject().apply {
                //     put("reason", "PAYMENT_DATA_INVALID")
                //     put("intent", "PAYMENT_AUTHORIZATION")
                //     put("message", "Invalid payment method.")
                // })
            }
    
            val response = PaymentAuthorizationResult.fromJson(responseJson.toString())
            onCompleteListener.complete(response)
        }
    }
  3. Host the callback service.

    import androidx.annotation.NonNull
    import com.google.android.gms.wallet.callback.BasePaymentDataCallbacks
    import com.google.android.gms.wallet.callback.BasePaymentDataCallbacksService
    
    /**
     * Service class which hosts the payment data callbacks.
     */
    class MerchantPaymentDataCallbacksService : BasePaymentDataCallbacksService() {
    
        @NonNull
        override fun createPaymentDataCallbacks(): BasePaymentDataCallbacks {
            return MerchantPaymentDataCallbacks()
        }
    }
  4. Update the AndroidManifest – declare the service and protect it with the BIND_PAYMENTS_CALLBACK_SERVICE permission.

    
        
            
        
    

You’re now ready to integrate dynamic callbacks and deliver a seamless Express Checkout experience with Google Pay on Android. 🚀

4. Configure the Payment Request

Finally, include the callbackIntents in your PaymentDataRequest JSON object to tell Google Pay which events you want to listen for.

{
  "apiVersion": 2,
  "apiVersionMinor": 0,

  "callbackIntents": [
    "PAYMENT_AUTHORIZATION",
    "SHIPPING_ADDRESS",
    "SHIPPING_OPTION"
  ]
}

Takeaways

Implementing dynamic callbacks on Android allows you to:

  • Reduce Friction: Enable a 1‑click experience by moving checkout upstream.
  • Increase Accuracy: Provide real‑time shipping and tax pricing.
  • Improve Authorization: Handle success or failure feedback within the Pay sheet to increase conversion.

Dynamic callbacks bring the Google Pay developer platform on Android to parity with its capabilities on the web. For a full implementation guide, see the updated developer documentation:


Service Declaration (for reference)


    
        
    
0 views
Back to Blog

Related posts

Read more »

The latest updates to Google Pay

May 27, 2026 At Google I/O, we explored how Google Pay is evolving for the era of agentic commerce. We shared a variety of powerful new capabilities for the Go...