Skip to content

Commit 4b98362

Browse files
committed
credit card section
1 parent 3c6dd72 commit 4b98362

File tree

5 files changed

+215
-121
lines changed

5 files changed

+215
-121
lines changed

examples/react/src/components/Connected.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
useOpenConnectModal,
1616
useWallets
1717
} from '@0xsequence/connect'
18-
import { Button, Card, Modal, Select, Switch, Text, TextInput, cn } from '@0xsequence/design-system'
18+
import { Button, Card, Modal, Scroll, Select, Switch, Text, TextInput, cn } from '@0xsequence/design-system'
1919
import { allNetworks, ChainId } from '@0xsequence/network'
2020
import { useOpenWalletModal } from '@0xsequence/wallet-widget'
2121
import { CardButton, Header, WalletListItem } from 'example-shared-components'
@@ -828,7 +828,9 @@ export const Connected = () => {
828828
scroll={false}
829829
onClose={() => setIsOpenCustomCheckout(false)}
830830
>
831-
<CustomCheckout />
831+
<Scroll style={{ height: '600px' }}>
832+
<CustomCheckout />
833+
</Scroll>
832834
</Modal>
833835
)}
834836
</AnimatePresence>

examples/react/src/components/CustomCheckout.tsx

Lines changed: 0 additions & 81 deletions
This file was deleted.
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import { Text, Button, Spinner, NetworkImage, Image } from '@0xsequence/design-system'
2+
import { useCheckoutUI, CreditCardProviders } from '@0xsequence/checkout'
3+
import { encodeFunctionData, toHex } from 'viem'
4+
import { useAccount } from 'wagmi'
5+
import { ERC_1155_SALE_CONTRACT } from '../../constants/erc1155-sale-contract'
6+
7+
export const CustomCheckout = () => {
8+
const { address } = useAccount()
9+
10+
// NATIVE token sale
11+
// const currencyAddress = zeroAddress
12+
// const salesContractAddress = '0xf0056139095224f4eec53c578ab4de1e227b9597'
13+
// const collectionAddress = '0x92473261f2c26f2264429c451f70b0192f858795'
14+
// const price = '200000000000000'
15+
// const contractId = '674eb55a3d739107bbd18ecb'
16+
17+
// // ERC-20 contract
18+
const currencyAddress = '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359'
19+
const salesContractAddress = '0xe65b75eb7c58ffc0bf0e671d64d0e1c6cd0d3e5b'
20+
const collectionAddress = '0xdeb398f41ccd290ee5114df7e498cf04fac916cb'
21+
const price = '20000'
22+
const contractId = '674eb5613d739107bbd18ed2'
23+
24+
const chainId = 137
25+
26+
const collectible = {
27+
tokenId: '1',
28+
quantity: '1'
29+
}
30+
31+
const purchaseTransactionData = encodeFunctionData({
32+
abi: ERC_1155_SALE_CONTRACT,
33+
functionName: 'mint',
34+
// [to, tokenIds, amounts, data, expectedPaymentToken, maxTotal, proof]
35+
args: [
36+
address,
37+
[BigInt(collectible.tokenId)],
38+
[BigInt(collectible.quantity)],
39+
toHex(0),
40+
currencyAddress,
41+
price,
42+
[toHex(0, { size: 32 })]
43+
]
44+
})
45+
46+
const checkoutUIParams = {
47+
collectible,
48+
chain: chainId,
49+
totalPriceRaw: price,
50+
targetContractAddress: salesContractAddress,
51+
recipientAddress: address || '',
52+
currencyAddress,
53+
collectionAddress,
54+
creditCardProvider: 'sardine' as CreditCardProviders,
55+
transakConfig: {
56+
contractId,
57+
apiKey: '5911d9ec-46b5-48fa-a755-d59a715ff0cf'
58+
},
59+
onSuccess: (txnHash: string) => {
60+
console.log('success!', txnHash)
61+
},
62+
onError: (error: Error) => {
63+
console.error(error)
64+
},
65+
txData: purchaseTransactionData
66+
}
67+
68+
const { orderSummary, creditCardPayment, cryptoPayment } = useCheckoutUI(checkoutUIParams)
69+
70+
console.log('orderSummary', orderSummary)
71+
console.log('creditCardPayment', creditCardPayment)
72+
console.log('cryptoPayment', cryptoPayment)
73+
74+
const OrderSummary = () => {
75+
if (orderSummary.isLoading) {
76+
return <Spinner />
77+
}
78+
79+
if (orderSummary.error) {
80+
return <Text color="error">Error loading order summary</Text>
81+
}
82+
83+
return (
84+
<div className="flex flex-col gap-2">
85+
<div className="flex flex-row gap-1">
86+
<div className="flex gap-3 items-center" key={collectible.tokenId}>
87+
<div
88+
className="rounded-xl"
89+
style={{
90+
height: '36px',
91+
width: '36px'
92+
}}
93+
>
94+
<Image src={orderSummary.data?.collectibleItem?.collectibleImageUrl} />
95+
</div>
96+
<div className="flex flex-col gap-0.5">
97+
<Text variant="small" color="secondary" fontWeight="medium">
98+
{orderSummary.data?.collectibleItem?.collectionName}
99+
</Text>
100+
<Text variant="small" color="primary" fontWeight="bold">
101+
{`${orderSummary.data?.collectibleItem?.collectibleName} x${orderSummary.data?.collectibleItem?.quantityFormatted}`}
102+
</Text>
103+
</div>
104+
</div>
105+
</div>
106+
<div className="flex gap-1 flex-col">
107+
<div className="flex flex-row gap-2 items-center">
108+
<NetworkImage chainId={chainId} size="sm" />
109+
<Text
110+
color="white"
111+
variant="large"
112+
fontWeight="bold"
113+
>{`${orderSummary?.data?.formattedCryptoPrice} ${orderSummary?.data?.cryptoSymbol}`}</Text>
114+
</div>
115+
<div>
116+
<Text color="muted" variant="normal" fontWeight="normal">
117+
{`$${orderSummary?.data?.totalPriceFiat} estimated total`}
118+
</Text>
119+
</div>
120+
</div>
121+
</div>
122+
)
123+
}
124+
125+
const CreditCardPayment = () => {
126+
if (creditCardPayment.isLoading) {
127+
return <Spinner />
128+
}
129+
130+
if (creditCardPayment.error) {
131+
return <Text color="error">Error loading credit card payment</Text>
132+
}
133+
134+
const CreditCardIframe = creditCardPayment.data?.CreditCardIframe
135+
const EventListener = creditCardPayment.data?.EventListener
136+
137+
return (
138+
<div>
139+
<CreditCardIframe />
140+
<EventListener />
141+
</div>
142+
)
143+
}
144+
145+
const CryptoPayment = () => {
146+
return <div>Crypto Payment</div>
147+
}
148+
149+
return (
150+
<div className="flex pt-16 pb-8 px-6 gap-2 flex-col">
151+
<Text color="primary">The following data is generated by the useCheckoutUI hook</Text>
152+
<Text fontSize="large" fontWeight="bold" color="primary">
153+
Order Summary section
154+
</Text>
155+
<OrderSummary />
156+
<Text fontSize="large" fontWeight="bold" color="primary">
157+
Crypto Payment section
158+
</Text>
159+
<CryptoPayment />
160+
<Text fontSize="large" fontWeight="bold" color="primary">
161+
Credit Card Payment section
162+
</Text>
163+
{/* <CreditCardPayment /> */}
164+
</div>
165+
)
166+
}
167+
168+
export default CustomCheckout

packages/checkout/src/hooks/useCheckoutUI/useCreditCardPayment.tsx

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ export interface UseCreditCardPaymentArgs {
4848
interface UseCreditCardPaymentData {
4949
iframeId: string
5050
paymentUrl?: string
51-
CreditCardIframe?: React.ReactElement
52-
EventListener?: React.ReactElement
51+
CreditCardIframe: React.ComponentType
52+
EventListener: React.ComponentType
5353
}
5454

5555
export interface UseCreditCardPaymentReturn {
5656
error: Error | null
57-
data: UseCreditCardPaymentData | null
57+
data: UseCreditCardPaymentData
5858
isLoading: boolean
5959
}
6060

@@ -129,15 +129,23 @@ export const useCreditCardPayment = ({
129129
if (missingCreditCardProvider || missingTransakConfig) {
130130
return {
131131
error: new Error('Missing credit card provider or transak config'),
132-
data: null,
132+
data: {
133+
iframeId: '',
134+
CreditCardIframe: () => null,
135+
EventListener: () => null
136+
},
133137
isLoading: false
134138
}
135139
}
136140

137141
if (error || isLoading) {
138142
return {
139143
error,
140-
data: null,
144+
data: {
145+
iframeId: '',
146+
CreditCardIframe: () => null,
147+
EventListener: () => null
148+
},
141149
isLoading
142150
}
143151
}
@@ -186,7 +194,7 @@ export const useCreditCardPayment = ({
186194
data: {
187195
iframeId: TRANSAK_IFRAME_ID,
188196
paymentUrl: transakLink,
189-
CreditCardIframe: (
197+
CreditCardIframe: () => (
190198
<div className="flex items-center justify-center" style={{ height: '770px' }}>
191199
<iframe
192200
id="transakIframe"
@@ -201,7 +209,7 @@ export const useCreditCardPayment = ({
201209
/>
202210
</div>
203211
),
204-
EventListener: (
212+
EventListener: () => (
205213
<TransakEventListener
206214
transactionConfirmations={transactionConfirmations}
207215
chainId={network?.chainId || 137}
@@ -222,36 +230,33 @@ export const useCreditCardPayment = ({
222230
const isLoadingSardine = isLoadingClientToken || isLoading
223231
const errorSardine = errorClientToken || error
224232

225-
const data =
226-
!isLoadingSardine && !errorSardine
227-
? {
228-
iframeId: SARDINE_IFRAME_ID,
229-
paymentUrl: url,
230-
CreditCardIframe: (
231-
<div className="flex items-center justify-center" style={{ height: '770px' }}>
232-
<iframe
233-
id={SARDINE_IFRAME_ID}
234-
src={url}
235-
style={{
236-
maxHeight: '650px',
237-
height: '100%',
238-
maxWidth: '380px',
239-
width: '100%'
240-
}}
241-
/>
242-
</div>
243-
),
244-
EventListener: (
245-
<SardineEventListener
246-
transactionConfirmations={transactionConfirmations}
247-
chainId={network?.chainId || 137}
248-
onSuccess={onSuccess}
249-
onError={onError}
250-
orderId={dataClientToken?.orderId || ''}
251-
/>
252-
)
253-
}
254-
: null
233+
const data = {
234+
iframeId: SARDINE_IFRAME_ID,
235+
paymentUrl: url,
236+
CreditCardIframe: () => (
237+
<div className="flex items-center justify-center" style={{ height: '770px' }}>
238+
<iframe
239+
id={SARDINE_IFRAME_ID}
240+
src={url}
241+
style={{
242+
maxHeight: '650px',
243+
height: '100%',
244+
maxWidth: '380px',
245+
width: '100%'
246+
}}
247+
/>
248+
</div>
249+
),
250+
EventListener: () => (
251+
<SardineEventListener
252+
transactionConfirmations={transactionConfirmations}
253+
chainId={network?.chainId || 137}
254+
onSuccess={onSuccess}
255+
onError={onError}
256+
orderId={dataClientToken?.orderId || ''}
257+
/>
258+
)
259+
}
255260

256261
return {
257262
error: errorSardine,

0 commit comments

Comments
 (0)