Skip to content

[SDK] Add enableCard prop to control fiat payment visibility #7465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 28, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/dull-breads-start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"thirdweb": patch
---

Adds paymentMethods prop to BuyWidget, CheckoutWidget, and TransactionWidget to control available payment options. Accepts an array of "crypto" and/or "card" values.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ export interface BridgeOrchestratorProps {
* Quick buy amounts
*/
presetOptions: [number, number, number] | undefined;

/**
* Allowed payment methods
* @default ["crypto", "card"]
*/
paymentMethods?: ("crypto" | "card")[];
}

export function BridgeOrchestrator({
Expand All @@ -127,6 +133,7 @@ export function BridgeOrchestrator({
purchaseData,
paymentLinkId,
presetOptions,
paymentMethods = ["crypto", "card"],
}: BridgeOrchestratorProps) {
// Initialize adapters
const adapters = useMemo(
Expand Down Expand Up @@ -271,6 +278,7 @@ export function BridgeOrchestrator({
onError={handleError}
onPaymentMethodSelected={handlePaymentMethodSelected}
receiverAddress={state.context.receiverAddress}
paymentMethods={paymentMethods}
/>
)}

Expand Down
7 changes: 7 additions & 0 deletions packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ export type BuyWidgetProps = {
* @hidden
*/
paymentLinkId?: string;

/**
* Allowed payment methods
* @default ["crypto", "card"]
*/
paymentMethods?: ("crypto" | "card")[];
};

// Enhanced UIOptions to handle unsupported token state
Expand Down Expand Up @@ -382,6 +388,7 @@ export function BuyWidget(props: BuyWidgetProps) {
purchaseData={props.purchaseData}
receiverAddress={undefined}
uiOptions={bridgeDataQuery.data.data}
paymentMethods={props.paymentMethods}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ export type CheckoutWidgetProps = {
* @hidden
*/
paymentLinkId?: string;

/**
* Allowed payment methods
* @default ["crypto", "card"]
*/
paymentMethods?: ("crypto" | "card")[];
};

// Enhanced UIOptions to handle unsupported token state
Expand Down Expand Up @@ -345,6 +351,7 @@ export function CheckoutWidget(props: CheckoutWidgetProps) {
purchaseData={props.purchaseData}
receiverAddress={props.seller}
uiOptions={bridgeDataQuery.data.data}
paymentMethods={props.paymentMethods}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ export type TransactionWidgetProps = {
* @hidden
*/
paymentLinkId?: string;

/**
* Allowed payment methods
* @default ["crypto", "card"]
*/
paymentMethods?: ("crypto" | "card")[];
};

// Enhanced UIOptions to handle unsupported token state
Expand Down Expand Up @@ -404,6 +410,7 @@ export function TransactionWidget(props: TransactionWidgetProps) {
purchaseData={props.purchaseData}
receiverAddress={undefined}
uiOptions={bridgeDataQuery.data.data}
paymentMethods={props.paymentMethods}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ export interface PaymentSelectionProps {
* Whether to include the destination token in the payment methods
*/
includeDestinationToken?: boolean;

/**
* Allowed payment methods
* @default ["crypto", "card"]
*/
paymentMethods?: ("crypto" | "card")[];
}

type Step =
Expand All @@ -90,6 +96,7 @@ export function PaymentSelection({
connectOptions,
connectLocale,
includeDestinationToken,
paymentMethods = ["crypto", "card"],
}: PaymentSelectionProps) {
const connectedWallets = useConnectedWallets();
const activeWallet = useActiveWallet();
Expand Down Expand Up @@ -248,6 +255,7 @@ export function PaymentSelection({
onConnectWallet={handleConnectWallet}
onFiatSelected={handleFiatSelected}
onWalletSelected={handleWalletSelected}
paymentMethods={paymentMethods}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface WalletFiatSelectionProps {
onWalletSelected: (wallet: Wallet) => void;
onFiatSelected: () => void;
onConnectWallet: () => void;
paymentMethods?: ("crypto" | "card")[];
}

export function WalletFiatSelection({
Expand All @@ -29,6 +30,7 @@ export function WalletFiatSelection({
onWalletSelected,
onFiatSelected,
onConnectWallet,
paymentMethods = ["crypto", "card"],
}: WalletFiatSelectionProps) {
const theme = useCustomTheme();

Expand Down Expand Up @@ -126,47 +128,50 @@ export function WalletFiatSelection({
</Container>
</Button>

<Spacer y="md" />
{paymentMethods.includes("card") && (
<>
<Spacer y="md" />

{/* Pay with Debit Card */}
<Text color="primaryText" size="md">
Pay with Fiat
</Text>
<Text color="primaryText" size="md">
Pay with Card
</Text>

<Spacer y="md" />
<Spacer y="md" />

<Button
fullWidth
onClick={onFiatSelected}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
height: "auto",
padding: `${spacing.sm} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
>
<Container
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
>
<CreditCardIcon
color={theme.colors.secondaryIconColor}
size={iconSize.lg}
/>
<Container flex="column" gap="3xs" style={{ flex: 1 }}>
<Text color="primaryText" size="sm" style={{ fontWeight: 600 }}>
Pay with Card
</Text>
<Text color="secondaryText" size="xs">
Buy crypto and bridge in one step
</Text>
</Container>
</Container>
</Button>
<Button
fullWidth
onClick={onFiatSelected}
style={{
backgroundColor: theme.colors.tertiaryBg,
border: `1px solid ${theme.colors.borderColor}`,
borderRadius: radius.md,
height: "auto",
padding: `${spacing.sm} ${spacing.md}`,
textAlign: "left",
}}
variant="secondary"
>
<Container
flex="row"
gap="md"
style={{ alignItems: "center", width: "100%" }}
>
<CreditCardIcon
color={theme.colors.secondaryIconColor}
size={iconSize.lg}
/>
<Container flex="column" gap="3xs" style={{ flex: 1 }}>
<Text color="primaryText" size="sm" style={{ fontWeight: 600 }}>
Pay with Card
</Text>
<Text color="secondaryText" size="xs">
Buy crypto and bridge in one step
</Text>
</Container>
</Container>
</Button>
</>
)}
</>
);
}
11 changes: 7 additions & 4 deletions packages/thirdweb/src/react/web/ui/PayEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export function PayEmbed(props: PayEmbedProps) {
onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
theme={theme}
title={metadata?.name || "Buy"}
paymentMethods={props.payOptions?.buyWithFiat === false ? ["crypto"] : ["crypto", "card"]}
tokenAddress={
props.payOptions.prefillBuy.token?.address as Address | undefined
}
Expand All @@ -377,6 +378,7 @@ export function PayEmbed(props: PayEmbedProps) {
name={metadata?.name || "Checkout"}
onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
seller={props.payOptions.paymentInfo.sellerAddress as Address}
paymentMethods={props.payOptions?.buyWithFiat === false ? ["crypto"] : ["crypto", "card"]}
theme={theme}
tokenAddress={
props.payOptions.paymentInfo.token?.address as Address | undefined
Expand All @@ -393,6 +395,7 @@ export function PayEmbed(props: PayEmbedProps) {
image={metadata?.image}
onSuccess={() => props.payOptions?.onPurchaseSuccess?.()}
theme={theme}
paymentMethods={props.payOptions?.buyWithFiat === false ? ["crypto"] : ["crypto", "card"]}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to do fiat only?

title={metadata?.name}
transaction={props.payOptions.transaction}
/>
Expand Down Expand Up @@ -513,10 +516,10 @@ export type PayEmbedConnectOptions = {
* ```
*/
autoConnect?:
| {
timeout: number;
}
| boolean;
| {
timeout: number;
}
| boolean;

/**
* Metadata of the app that will be passed to connected wallet. Setting this is highly recommended.
Expand Down
31 changes: 5 additions & 26 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading