Skip to content
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