Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
59 changes: 59 additions & 0 deletions apps/betterzeriya/src/lib/server/ucp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
interface UcpLineItem {
item: {
id: string
title?: string
}
quantity: number
}

interface UcpBuyer {
full_name?: string
email?: string
}

interface CreateCheckoutSessionInput {
line_items: UcpLineItem[]
buyer?: UcpBuyer
currency?: string
}

interface UcpCheckoutSession {
id: string
status: 'requires_action' | 'completed'
currency: string
buyer?: UcpBuyer
line_items: UcpLineItem[]
created_at: string
updated_at: string
}

const sessions = new Map<string, UcpCheckoutSession>()

export const createUcpCheckoutSession = (input: CreateCheckoutSessionInput) => {
const now = new Date().toISOString()
const session: UcpCheckoutSession = {
id: crypto.randomUUID(),
status: 'requires_action',
currency: input.currency ?? 'JPY',
buyer: input.buyer,
line_items: input.line_items,
created_at: now,
updated_at: now,
}
sessions.set(session.id, session)
return session
}

export const getUcpCheckoutSession = (id: string) => sessions.get(id)

export const completeUcpCheckoutSession = (id: string) => {
const session = sessions.get(id)
if (!session) return undefined
const updated = {
...session,
status: 'completed' as const,
updated_at: new Date().toISOString(),
}
sessions.set(id, updated)
Comment on lines +86 to +369
return updated
}
21 changes: 21 additions & 0 deletions apps/betterzeriya/src/routes/.well-known/ucp/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { json, type RequestHandler } from '@sveltejs/kit'

export const GET: RequestHandler = async ({ url }) => {
const origin = url.origin
return json({
name: 'betterzeriya',
version: '2026-01-11',
capabilities: [
{
name: 'dev.ucp.shopping.checkout',
bindings: [
{
type: 'rest',
spec: 'https://ucp.dev/specification/checkout-rest/',
base_url: `${origin}/api/ucp`,
},
],
},
],
})
}
26 changes: 26 additions & 0 deletions apps/betterzeriya/src/routes/api/ucp/checkout-sessions/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { json, type RequestHandler } from '@sveltejs/kit'
import { createUcpCheckoutSession } from '$lib/server/ucp'

export const POST: RequestHandler = async ({ request, url }) => {
const body = await request.json().catch(() => null)
const lineItems = body?.line_items

if (!Array.isArray(lineItems) || lineItems.length === 0) {
return json({ error: 'line_items is required' }, { status: 400 })
}

const session = createUcpCheckoutSession({
line_items: lineItems,
buyer: body?.buyer,
currency: body?.currency,
Comment thread
nakasyou marked this conversation as resolved.
Outdated
})

return json(
{
checkout_session: session,
checkout_url: `${url.origin}/sessions/${session.id}`,
status_url: `${url.origin}/api/ucp/checkout-sessions/${session.id}`,
},
{ status: 201 },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { json, type RequestHandler } from '@sveltejs/kit'
import { completeUcpCheckoutSession, getUcpCheckoutSession } from '$lib/server/ucp'

export const GET: RequestHandler = async ({ params }) => {
const session = getUcpCheckoutSession(params.id)
if (!session) {
return json({ error: 'Checkout session not found' }, { status: 404 })
}
return json({ checkout_session: session })
}

export const POST: RequestHandler = async ({ params }) => {
const session = completeUcpCheckoutSession(params.id)
if (!session) {
return json({ error: 'Checkout session not found' }, { status: 404 })
}
return json({ checkout_session: session })
}
1 change: 0 additions & 1 deletion bun.lock

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

Loading