<MoonPayGooglePayButton> renders a Google Pay button inline in your layout.
Google Pay availability depends on the device and environment. The component
emits
"unsupported" when Google Pay isn’t available — surface a fallback
payment method.GooglePaySection.tsx
import React from "react";
import {
MoonPayGooglePayButton,
MoonPayChallenge,
type GooglePayEvent,
} from "@moonpay/platform-sdk-react-native";
export function GooglePaySection({
quoteSignature,
}: {
quoteSignature: string;
}) {
const [challengeUrl, setChallengeUrl] = React.useState<string | null>(null);
const handleEvent = (event: GooglePayEvent) => {
switch (event.kind) {
case "ready":
break;
case "buttonPressed":
// Customer tapped the button — show a loading state or fire analytics.
break;
case "complete":
console.log(event.payload.transaction);
break;
case "quoteExpired":
// Fetch a new quote and update the prop, or call setQuote directly:
// event.payload.setQuote(newQuote.signature);
break;
case "challenge":
setChallengeUrl(event.payload.url);
break;
case "error":
console.error(event.payload.kind, event.payload.message);
break;
case "unsupported":
// Google Pay isn't available — fall back to another method.
break;
}
};
return (
<>
<MoonPayGooglePayButton quote={quoteSignature} onEvent={handleEvent} />
{challengeUrl && (
<MoonPayChallenge
url={challengeUrl}
onEvent={(e) => {
if (e.kind === "complete" || e.kind === "cancelled") {
setChallengeUrl(null);
}
}}
/>
)}
</>
);
}
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
quote | string | ✅ | — | Quote signature from getQuote(). Reactive — updating this prop pushes the new signature into the frame without a remount. |
externalTransactionId | string | — | Partner-assigned identifier for this transaction attempt. Mount-time only. | |
onEvent | (event: GooglePayEvent) => void | — | Callback for Google Pay lifecycle events. See GooglePayEvent. | |
style | ViewStyle | height: 48 | Container style. |
GooglePayEvent
Use event.kind to handle each event.
| kind | Payload | When you receive it |
|---|---|---|
"ready" | — | The Google Pay UI is rendered and ready. |
"buttonPressed" | — | The customer tapped the Google Pay button, before Android presents the Google Pay sheet. An intent-to-buy signal with no payload — it still fires if the customer then cancels the sheet. Not a purchase outcome; listen for "complete" for the result. |
"complete" | { transaction: FrameTransaction; sessionUpgraded?: true } | The payment finished. Inspect FrameTransaction for the outcome. After a guest checkout recovery that finished on this button with resume, it also carries sessionUpgraded: true: create a new session and check the connection again. |
"challenge" | { kind: "frame"; url: string } | Verification required. Render <MoonPayChallenge> with the provided URL. To have the customer pay on this button afterwards, open the challenge with resume: true and keep this button mounted. See Finish on your buy button. |
"quoteExpired" | { setQuote: (signature: string) => void } | The quote expired. Fetch a new quote and update the quote prop, or call payload.setQuote(...) directly. |
"error" | { kind: string; message: string } | The flow encountered an error. See error kinds below. |
"unsupported" | — | Google Pay isn’t available in the user’s environment. |
"error" kinds: "configurationError" | "invalidQuote" |
"quoteExpired" | "genericError"
Google Pay unavailability is signalled separately through the "unsupported"
event, not as an error.