惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
C
Check Point Blog
腾讯CDC
Stack Overflow Blog
Stack Overflow Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
Recent Announcements
Recent Announcements
L
LangChain Blog
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
J
Java Code Geeks
博客园_首页
Jina AI
Jina AI
美团技术团队
H
Help Net Security
MyScale Blog
MyScale Blog
Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
Y
Y Combinator Blog
S
SegmentFault 最新的问题

Google Developers Blog

Build zero-trust AI agents that judge intent, not just syntax- Google Developers Blog Autonomous LLM post-training with Tunix on TPUs- Google Developers Blog The Anatomy of Harness Engineering: How to Evaluate, Iterate, and Guard AI Coding Agents- Google Developers Blog Announcing ADK for Kotlin 1.0: Building Production-Ready AI Agents in Kotlin, Android, and Beyond- Google Developers Blog Driving Developer Excellence: Inside the Program Sprints- Google Developers Blog 4 engineering patterns behind the strongest AI Agents Challenge submissions- Google Developers Blog Decoding cosmic signals with deep learning and Keras- Google Developers Blog Enterprise-Grade Precision for Long-Context Multimodal Embedding Inference on Cloud TPU- Google Developers Blog How to Evaluate Live & Voice Agents in ADK- Google Developers Blog Build zero-trust AI agents with Google's Agent Development Kit- Google Developers Blog Introducing Credentio: Open Source C++ Library for C2PA Content Credentials from Google- Google Developers Blog HeyGen x Google Cloud: Bringing Avatar IV to TPUs- Google Developers Blog Why Go is an Ideal Language for AI-Assisted Software Engineering- Google Developers Blog Mastering Edge AI on Raspberry Pi with LiteRT and Gemma- Google Developers Blog Agent Plugins package your skills, tools, and more- Google Developers Blog Scaling AI Agent Infrastructure with the MCP Stateless updates- Google Developers Blog A unified API for AI model routing- Google Developers Blog Scaling real-time AI agents with session-aware load balancing- Google Developers Blog Agent and Model Evaluations in Gemini Enterprise Agent Platform are now GA- Google Developers Blog Enable on-demand expertise with Agent Skills in Genkit Go- Google Developers Blog How to use Google microbenchmarks for evaluating TPU performance- Google Developers Blog Run Ray on TPU, Part 2: Ray AI libraries- Google Developers Blog Scaling Agentic RL: High-Throughput Agentic Training with Tunix- Google Developers Blog Run Ray on TPU, Part 1: The foundations- Google Developers Blog Expanding Choice in Gemini Enterprise Agent Platform: Introducing Grounding with Parallel Web Search- Google Developers Blog Building scalable AI agents with modular prompt transpilation- Google Developers Blog Evolving Spec-Driven Development: Conductor Now Supports Antigravity- Google Developers Blog Systems Engineering Playbook: Optimizing Qwen 3.5-397B MoE on Ironwood (TPU7x)- Google Developers Blog Unlocking the Next Era of On-Device AI with Google Tensor and Pixel- Google Developers Blog LiteRT.js, Google's high performance Web AI Inference- Google Developers Blog
Enhancing Android Checkout with Dynamic Callbacks in Goog...
Dominik Mengelt, Nik Heath · 2026-05-26 · via Google Developers Blog

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 familiar callbacks onPaymentDataChanged and onPaymentAuthorized that are already supported on Web now 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, and handle authorization feedback without ever closing the sheet. This is available with play-services-wallet:20.0.0 and onwards.

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

To get started, update your Google Pay dependency in your build.gradle file:

com.google.android.gms:play-services-wallet:20.0.0

Kotlin

Copied

1. Implement the Callback Logic

Extend BasePaymentDataCallbacks to handle the specific events triggered during the checkout process.

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<PaymentDataRequestUpdate>
    ) {

        // Example: Process the request and return updates
        // In a real application, 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 {
            // Example: Add 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")
                })
            })

            // Example: Update 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<PaymentAuthorizationResult>
    ) {
        // Log the payment data for debugging
        println("onPaymentAuthorized called with PaymentData: ${request.toJson()}")

        // Example: Process the payment authorization
        // In a real application, 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)
    }
}

Kotlin

Copied

2. Host the Callback Service

Implement a service that extends BasePaymentDataCallbacksService to provide an instance of your callbacks.

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()
    }
}

Kotlin

Copied

3. Update the Android Manifest

You must declare your service and protect it with the BIND_PAYMENTS_CALLBACK_SERVICE permission.

<service
    android:name=".service.MerchantPaymentDataCallbacksService"
    android:permission="com.google.android.gms.permission.BIND_PAYMENTS_CALLBACK_SERVICE"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.wallet.callback.PAYMENT_DATA_CALLBACKS" />
    </intent-filter>
</service>

XML

Copied

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"
  ]
}

JSON

Copied

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: goo.gle/pay-android-dpu