Skip to content

Commit 022355f

Browse files
set up nextjs example checkout app
1 parent 74f228c commit 022355f

File tree

9 files changed

+7844
-7731
lines changed

9 files changed

+7844
-7731
lines changed

examples/nextjs/app/checkout.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'use client';
2+
3+
import type { CheckoutFormSchema, CheckoutSession } from '@godaddy/react';
4+
import { Checkout, GoDaddyProvider } from '@godaddy/react';
5+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
6+
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
7+
import { useState } from 'react';
8+
import { z } from 'zod';
9+
10+
/* Override the checkout form schema to make shippingPhone required */
11+
const customSchema: CheckoutFormSchema = {
12+
shippingPhone: z.string().min(1, 'Phone number is required'),
13+
};
14+
15+
export function CheckoutPage({ session }: { session: CheckoutSession }) {
16+
const [queryClient] = useState(() => new QueryClient());
17+
18+
return (
19+
<QueryClientProvider client={queryClient}>
20+
<GoDaddyProvider>
21+
<Checkout
22+
session={session}
23+
checkoutFormSchema={customSchema}
24+
squareConfig={{
25+
appId: process.env.NEXT_PUBLIC_SQUARE_APP_ID || '',
26+
locationId: process.env.NEXT_PUBLIC_SQUARE_LOCATION_ID || '',
27+
}}
28+
stripeConfig={{
29+
publishableKey:
30+
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY || '',
31+
}}
32+
godaddyPaymentsConfig={{
33+
businessId: process.env.NEXT_PUBLIC_GODADDY_BUSINESS_ID || '',
34+
appId: process.env.NEXT_PUBLIC_GODADDY_APP_ID || '',
35+
}}
36+
paypalConfig={{
37+
clientId: process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID || '',
38+
}}
39+
/>
40+
<ReactQueryDevtools initialIsOpen={false} />
41+
</GoDaddyProvider>
42+
</QueryClientProvider>
43+
);
44+
}

examples/nextjs/app/layout.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Metadata } from 'next';
22
import { Geist, Geist_Mono } from 'next/font/google';
33
import './globals.css';
4+
import '@godaddy/react/styles.css';
45

56
const geistSans = Geist({
67
variable: '--font-geist-sans',

examples/nextjs/app/page.tsx

Lines changed: 104 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,107 @@
1-
import Image from 'next/image';
1+
import { createCheckoutSession } from '@godaddy/react/server';
2+
import { unstable_noStore } from 'next/cache';
3+
import { notFound } from 'next/navigation';
4+
import { CheckoutPage } from './checkout';
25

3-
export default function Home() {
4-
return (
5-
<div className='flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black'>
6-
<main className='flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start'>
7-
<Image
8-
className='dark:invert'
9-
src='/next.svg'
10-
alt='Next.js logo'
11-
width={100}
12-
height={20}
13-
priority
14-
/>
15-
<div className='flex flex-col items-center gap-6 text-center sm:items-start sm:text-left'>
16-
<h1 className='max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50'>
17-
To get started, edit the page.tsx file.
18-
</h1>
19-
<p className='max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400'>
20-
Looking for a starting point or more instructions? Head over to{' '}
21-
<a
22-
href='https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app'
23-
className='font-medium text-zinc-950 dark:text-zinc-50'
24-
>
25-
Templates
26-
</a>{' '}
27-
or the{' '}
28-
<a
29-
href='https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app'
30-
className='font-medium text-zinc-950 dark:text-zinc-50'
31-
>
32-
Learning
33-
</a>{' '}
34-
center.
35-
</p>
36-
</div>
37-
<div className='flex flex-col gap-4 text-base font-medium sm:flex-row'>
38-
<a
39-
className='flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]'
40-
href='https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app'
41-
target='_blank'
42-
rel='noopener noreferrer'
43-
>
44-
<Image
45-
className='dark:invert'
46-
src='/vercel.svg'
47-
alt='Vercel logomark'
48-
width={16}
49-
height={16}
50-
/>
51-
Deploy Now
52-
</a>
53-
<a
54-
className='flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]'
55-
href='https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app'
56-
target='_blank'
57-
rel='noopener noreferrer'
58-
>
59-
Documentation
60-
</a>
61-
</div>
62-
</main>
63-
</div>
6+
export const dynamic = 'force-dynamic';
7+
8+
export default async function Home() {
9+
unstable_noStore();
10+
const session = await createCheckoutSession(
11+
{
12+
environment:
13+
(process.env.GODADDY_ENVIRONMENT as 'dev' | 'test' | 'ote' | 'prod') ||
14+
'dev',
15+
returnUrl: 'https://godaddy.com',
16+
successUrl: 'https://godaddy.com/success',
17+
draftOrderId: process.env.NEXT_PUBLIC_GODADDY_DRAFT_ORDER_ID || '',
18+
storeId: process.env.NEXT_PUBLIC_GODADDY_STORE_ID || '',
19+
channelId: process.env.NEXT_PUBLIC_GODADDY_CHANNEL_ID || '',
20+
enableLocalPickup: true,
21+
enableShippingAddressCollection: true,
22+
enableBillingAddressCollection: true,
23+
enablePhoneCollection: true,
24+
enableTaxCollection: true,
25+
enableNotesCollection: true,
26+
enablePromotionCodes: true,
27+
shipping: {
28+
fulfillmentLocationId: 'default-location',
29+
originAddress: {
30+
addressLine1: '1600 Pennsylvania Ave NW',
31+
adminArea1: 'DC',
32+
adminArea3: 'Washington',
33+
countryCode: 'US',
34+
postalCode: '20500',
35+
},
36+
},
37+
taxes: {
38+
originAddress: {
39+
addressLine1: '1600 Pennsylvania Ave NW',
40+
adminArea1: 'DC',
41+
adminArea3: 'Washington',
42+
countryCode: 'US',
43+
postalCode: '20500',
44+
},
45+
},
46+
locations: [
47+
{
48+
id: 'default-location',
49+
isDefault: true,
50+
address: {
51+
addressLine1: '1600 Pennsylvania Ave NW',
52+
adminArea1: 'DC',
53+
adminArea3: 'Washington',
54+
countryCode: 'US',
55+
postalCode: '20500',
56+
},
57+
},
58+
],
59+
paymentMethods: {
60+
card: {
61+
processor: 'godaddy',
62+
checkoutTypes: ['standard'],
63+
},
64+
express: {
65+
processor: 'godaddy',
66+
checkoutTypes: ['express'],
67+
},
68+
paypal: {
69+
processor: 'paypal',
70+
checkoutTypes: ['standard'],
71+
},
72+
offline: {
73+
processor: 'offline',
74+
checkoutTypes: ['standard'],
75+
},
76+
},
77+
operatingHours: {
78+
default: {
79+
timeZone: 'America/New_York', // CDT timezone
80+
leadTime: 60, // 60 minutes lead time
81+
pickupWindowInDays: 7,
82+
hours: {
83+
monday: { enabled: true, openTime: '09:00', closeTime: '17:00' },
84+
tuesday: { enabled: true, openTime: '09:00', closeTime: '17:00' },
85+
wednesday: { enabled: false, openTime: null, closeTime: null },
86+
thursday: { enabled: true, openTime: '09:00', closeTime: '17:00' },
87+
friday: { enabled: true, openTime: '09:00', closeTime: '18:00' },
88+
saturday: { enabled: true, openTime: '10:00', closeTime: '16:00' },
89+
sunday: { enabled: true, openTime: '12:00', closeTime: '15:00' },
90+
},
91+
},
92+
},
93+
},
94+
{
95+
auth: {
96+
clientId: process.env.GODADDY_CLIENT_ID || '',
97+
clientSecret: process.env.GODADDY_CLIENT_SECRET || '',
98+
},
99+
}
64100
);
101+
102+
if (!session) {
103+
throw notFound();
104+
}
105+
106+
return <CheckoutPage session={session} />;
65107
}

examples/nextjs/env.sample

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# GoDaddy API Credentials
2+
GODADDY_CLIENT_ID=
3+
GODADDY_CLIENT_SECRET=
4+
NEXT_PUBLIC_GODADDY_ENV=test|dev|prod
5+
NEXT_PUBLIC_GODADDY_HOST=api.godaddy.com
6+
7+
# Store and Order Identifiers
8+
NEXT_PUBLIC_GODADDY_STORE_ID=
9+
NEXT_PUBLIC_GODADDY_CHANNEL_ID=
10+
NEXT_PUBLIC_GODADDY_DRAFT_ORDER_ID=
11+
12+
# Stripe Payment Credentials
13+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
14+
STRIPE_SECRET=
15+
16+
# GoDaddy Payment Credentials
17+
NEXT_PUBLIC_GODADDY_APP_ID=
18+
#NEXT_PUBLIC_GODADDY_BUSINESS_ID=
19+
20+
# Square Credentials
21+
NEXT_PUBLIC_SQUARE_APP_ID=
22+
NEXT_PUBLIC_SQUARE_LOCATION_ID=
23+
NEXT_PUBLIC_PAYPAL_CLIENT_ID=

examples/nextjs/package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,19 @@
1414
"@godaddy/react": "workspace:*",
1515
"@tanstack/react-query": "^5.66.0",
1616
"@tanstack/react-query-devtools": "^5.76.1",
17+
"next": "16.0.1",
1718
"react": "19.2.0",
1819
"react-dom": "19.2.0",
19-
"next": "16.0.1"
20+
"zod": "^3.24.1"
2021
},
2122
"devDependencies": {
22-
"typescript": "^5",
2323
"@biomejs/biome": "^2",
24+
"@tailwindcss/postcss": "^4",
2425
"@types/node": "^20",
2526
"@types/react": "^19",
2627
"@types/react-dom": "^19",
27-
"@tailwindcss/postcss": "^4",
2828
"biome-config-godaddy": "workspace:*",
29-
"tailwindcss": "^4"
29+
"tailwindcss": "^4",
30+
"typescript": "^5"
3031
}
3132
}

packages/react/src/components/checkout/checkout.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,10 @@ export const baseCheckoutSchema = z.object({
182182
stripePaymentIntentId: z.string().optional(),
183183
}); // We cannot use refine here, as it would not allow extending the schema with session overrides.
184184

185-
export type CheckoutFormSchema = {
186-
[K in keyof z.infer<typeof baseCheckoutSchema>]?: z.ZodTypeAny;
187-
} & {
188-
[key: string]: z.ZodTypeAny;
189-
};
185+
export type CheckoutFormSchema = Partial<{
186+
[K in keyof z.infer<typeof baseCheckoutSchema>]: z.ZodTypeAny;
187+
}> &
188+
z.ZodRawShape;
190189

191190
export type CheckoutFormData = z.infer<typeof baseCheckoutSchema>;
192191

packages/react/src/components/checkout/payment/checkout-buttons/express/godaddy.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ export function ExpressCheckoutButton() {
378378
return;
379379

380380
collect.current?.supportWalletPayments().then(supports => {
381-
const paymentMethods = [];
381+
const paymentMethods: string[] = [];
382382
if (supports.applePay) {
383383
track({
384384
eventId: eventIds.expressApplePayImpression,

0 commit comments

Comments
 (0)