Skip to content
Open
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# saizeriya

[![技術者倫理 遵守済み](https://img.shields.io/badge/%E6%8A%80%E8%A1%93%E8%80%85%E5%80%AB%E7%90%86-%E9%81%B5%E5%AE%88%E6%B8%88%E3%81%BF-0a0a0a?style=for-the-badge&labelColor=ffffff)](https://技術者倫理.com)

<!-- なんとなく追加 -->
<!-- [![技術者倫理|遵守済み](https://gijutsusharin.li/badge.svg)](https://gijutsusharin.li) -->

Expand Down
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