diff --git a/.changeset/small-boxes-grow.md b/.changeset/small-boxes-grow.md
new file mode 100644
index 00000000000..6126a442073
--- /dev/null
+++ b/.changeset/small-boxes-grow.md
@@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
+Add support for filtering fiat payment providers in PayEmbed
diff --git a/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts b/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts
index 33df86e34ce..4a44f084e5c 100644
--- a/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts
+++ b/packages/thirdweb/src/react/core/hooks/connection/ConnectButtonProps.ts
@@ -98,6 +98,7 @@ export type PayUIOptions = Prettify<
currency?: CurrencyMeta["shorthand"];
};
preferredProvider?: FiatProvider;
+ supportedProviders?: FiatProvider[];
}
| false;
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayProviderSelection.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayProviderSelection.tsx
new file mode 100644
index 00000000000..905ebcc52c1
--- /dev/null
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/PayProviderSelection.tsx
@@ -0,0 +1,68 @@
+import { ChevronDownIcon } from "@radix-ui/react-icons";
+import type { FiatProvider } from "../../../../../../pay/utils/commonTypes.js";
+import { iconSize, spacing } from "../../../../../core/design-system/index.js";
+import { Container } from "../../../components/basic.js";
+import { Button } from "../../../components/buttons.js";
+import { Text } from "../../../components/text.js";
+import { getProviderLabel } from "./utils.js";
+
+/**
+ * Shows the selected payment provider based on the preferred provider OR the quoted provider.
+ * @internal
+ */
+export const PayProviderSelection = (props: {
+ onShowProviders: () => void;
+ quotedProvider?: FiatProvider;
+ preferredProvider?: FiatProvider;
+ supportedProviders: FiatProvider[];
+}) => {
+ const ProviderItem = (
+
+
+ {getProviderLabel(
+ props.preferredProvider ?? props.quotedProvider ?? "",
+ )}
+
+ {props.supportedProviders.length > 1 && (
+
+ )}
+
+ );
+
+ return (
+
+
+ Provider
+
+ {props.supportedProviders.length > 1 ? (
+
+ ) : (
+ ProviderItem
+ )}
+
+ );
+};
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx
index 3b7bbc9e481..3e6d83954e2 100644
--- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx
@@ -1,15 +1,13 @@
-import { ChevronDownIcon } from "@radix-ui/react-icons";
import { useState } from "react";
import { trackPayEvent } from "../../../../../../../analytics/track/pay.js";
import type { Chain } from "../../../../../../../chains/types.js";
import type { ThirdwebClient } from "../../../../../../../client/client.js";
import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js";
-import type { FiatProvider } from "../../../../../../../pay/utils/commonTypes.js";
import {
- type Theme,
- iconSize,
- spacing,
-} from "../../../../../../core/design-system/index.js";
+ type FiatProvider,
+ FiatProviders,
+} from "../../../../../../../pay/utils/commonTypes.js";
+import type { Theme } from "../../../../../../core/design-system/index.js";
import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
import { useBuyWithFiatQuote } from "../../../../../../core/hooks/pay/useBuyWithFiatQuote.js";
import { PREFERRED_FIAT_PROVIDER_STORAGE_KEY } from "../../../../../../core/utils/storage.js";
@@ -26,6 +24,7 @@ import { Button } from "../../../../components/buttons.js";
import { Text } from "../../../../components/text.js";
import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
import { EstimatedTimeAndFees } from "../EstimatedTimeAndFees.js";
+import { PayProviderSelection } from "../PayProviderSelection.js";
import { PayWithCreditCard } from "../PayWIthCreditCard.js";
import type { SelectedScreen } from "../main/types.js";
import { FiatFees } from "../swap/Fees.js";
@@ -84,6 +83,19 @@ export function FiatScreenContent(props: {
: undefined,
);
+ const supportedProviders = (() => {
+ if (!buyWithFiatOptions) return [...FiatProviders];
+ const options = buyWithFiatOptions?.supportedProviders ?? [];
+ const optionsWithPreferred =
+ options.length > 0
+ ? new Set([
+ ...(preferredProvider ? [preferredProvider] : []),
+ ...options,
+ ])
+ : FiatProviders;
+ return Array.from(optionsWithPreferred);
+ })();
+
const fiatQuoteQuery = useBuyWithFiatQuote(
buyWithFiatOptions !== false && tokenAmount
? {
@@ -98,8 +110,8 @@ export function FiatScreenContent(props: {
isTestMode: buyWithFiatOptions?.testMode,
purchaseData: props.payOptions.purchaseData,
fromAddress: payer.account.address,
- preferredProvider: preferredProvider,
paymentLinkId: paymentLinkId,
+ preferredProvider: preferredProvider ?? supportedProviders[0],
}
: undefined,
);
@@ -159,6 +171,7 @@ export function FiatScreenContent(props: {
-
-
- Provider
-
-
-
+ {/** Shows preferred or quoted provider and conditional selection */}
+
{/* Estimated time + View fees button */}
- {step.action.charAt(0).toUpperCase() + step.action.slice(1)}
+ {getProviderLabel(step.action)}
void;
}) {
@@ -21,37 +21,34 @@ export function Providers(props: {
alignItems: "flex-start",
}}
>
- {FiatProviders.map((provider) => {
- return (
- (
+
+
- );
- })}
+ {getProviderLabel(provider)}
+
+
+
+ ))}
);
}
diff --git a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/utils.ts b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/utils.ts
index 1266bdf0023..302cbd3387b 100644
--- a/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/utils.ts
+++ b/packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/utils.ts
@@ -1,3 +1,12 @@
export function getBuyTokenAmountFontSize(value: string) {
return value.length > 10 ? "26px" : value.length > 6 ? "34px" : "50px";
}
+
+/**
+ *
+ * @param str accepts any string but expects a fully upppercased string / type FiatProvider
+ * @returns Fiat provider label to be rendered used within presentation logic
+ */
+export function getProviderLabel(str: string) {
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
+}