04.a - Stripe-Checkout-Creation
Relevant source files
Purpose and ScopeLink copied!
This document details the createCheckoutSession server action, which initiates Stripe payment processing for the $10 DeepWiki Analysis product. This action creates a Stripe Checkout session, configures the product details, sets up success and cancellation URLs, and redirects the user to Stripe's hosted payment page.
For information about what happens after successful payment, see Stripe Webhook Handling. For the complete payment-to-installation linking mechanism, see Payment-to-Installation Linking.
OverviewLink copied!
The Stripe checkout flow begins when a user clicks either payment button on the landing page. The system uses Next.js 14 Server Actions to handle the checkout session creation server-side, ensuring secure API key handling and proper origin detection for redirect URLs.
Server Action Flow Diagram
Sources: app/actions.ts L1-L33
Server Action ImplementationLink copied!
The createCheckoutSession function is defined in app/actions.ts L7-L33
with the "use server" directive, marking it as a Next.js Server Action. This allows the function to execute on the server while being invoked directly from client components via form actions.
| Aspect | Implementation |
|---|---|
| Function Name | createCheckoutSession |
| File Location | app/actions.ts |
| Execution Context | Server-side only |
| Return Type | Promise<void> (redirects user) |
| Dependencies | stripe (from @/lib/stripe), headers (from next/headers), redirect (from next/navigation) |
The function performs three primary operations:
- Origin Detection: Extracts the request origin from HTTP headers
- Stripe Session Creation: Calls the Stripe API to create a checkout session
- User Redirect: Redirects the user to the Stripe-hosted checkout page
Sources: app/actions.ts L1-L6
Origin Detection and URL ConstructionLink copied!
The action uses Next.js headers() API to determine the deployment origin, which is essential for constructing absolute redirect URLs required by Stripe.
Origin Detection Logic
The code at app/actions.ts L8-L9
implements this pattern:
await headers(): Retrieves the request headers object.get("origin"): Extracts theOriginHTTP header value|| "http://localhost:3000": Provides a development fallback
This origin variable is then used to construct two critical URLs:
| URL Type | Pattern | Purpose |
|---|---|---|
| Success URL | ${origin}/success?session_id={CHECKOUT_SESSION_ID} | Redirect destination after successful payment |
| Cancel URL | ${origin}/?canceled=true | Redirect destination if user cancels payment |
The {CHECKOUT_SESSION_ID} placeholder is automatically replaced by Stripe with the actual session ID at redirect time.
Sources: app/actions.ts L8-L9
Stripe Checkout Session ConfigurationLink copied!
The core of the action is the stripe.checkout.sessions.create() call at app/actions.ts L11-L28
which configures the payment session with specific product details and behavior.
Checkout Session Configuration Structure
Sources: app/actions.ts L11-L28
Product Configuration DetailsLink copied!
The product is configured inline using Stripe's price_data API, which allows ad-hoc product creation without pre-defining price objects in the Stripe Dashboard.
| Field | Value | Notes |
|---|---|---|
currency | "usd" | United States Dollar |
product_data.name | "DeepWiki Analysis" | Displayed on checkout page |
product_data.description | "Full architectural documentation for your GitHub repository." | Additional product context |
unit_amount | 1000 | Price in cents ($10.00) |
quantity | 1 | Always 1 (single-repo analysis) |
mode | "payment" | One-time payment (not subscription) |
The unit_amount: 1000 at app/actions.ts L20
represents $10.00 because Stripe's API expects amounts in the smallest currency unit (cents for USD).
Sources: app/actions.ts L14-L21
Redirect URL PatternsLink copied!
The success and cancel URLs follow specific patterns designed to integrate with the application's user journey.
URL Pattern Mapping
Success URL DetailsLink copied!
The success URL at app/actions.ts L26
uses the placeholder {CHECKOUT_SESSION_ID}, which Stripe automatically replaces with the actual session ID when redirecting. This pattern:
- Ensures type safety (no manual string interpolation of session IDs)
- Allows the success page to retrieve session details from Stripe
- Serves as the correlation key for linking payment to GitHub installation (see Payment-to-Installation Linking)
The URL resolves to: https://godeep.wiki/success?session_id=cs_test_... (in production)
Cancel URL DetailsLink copied!
The cancel URL at app/actions.ts L27
includes a canceled=true query parameter. While the current implementation does not explicitly check this parameter on the landing page, it provides a mechanism for future UI enhancements (e.g., displaying a "Payment was cancelled" message).
Sources: app/actions.ts L26-L27
Session Creation and Response HandlingLink copied!
After configuring the session parameters, the action creates the session and handles the response.
Session Creation Flow
The response handling at app/actions.ts L30-L32
checks for the presence of session.url before redirecting. The Stripe API response includes:
| Field | Type | Description |
|---|---|---|
id | string | Unique session identifier (e.g., cs_test_a1b2c3...) |
url | string | Stripe-hosted checkout page URL |
amount_total | number | Total amount in cents (1000) |
currency | string | Currency code (usd) |
payment_status | string | Initial status (unpaid) |
The redirect() function from Next.js triggers a 307 Temporary Redirect, sending the user to Stripe's hosted checkout page where they complete payment.
Sources: app/actions.ts L11-L32
Integration with Landing PageLink copied!
The createCheckoutSession action is invoked from two locations on the landing page, both using the same form action pattern.
Landing Page Integration Points
Form Implementation PatternLink copied!
Both forms follow the identical pattern:
- Import the server action:
import { createCheckoutSession } from "./actions"at app/page.tsx L5 - Create a form with
action={createCheckoutSession}attribute - Include a submit button (wrapped in
BeamButtoncomponent)
When the user clicks either button:
- The browser triggers form submission
- Next.js intercepts the submission and invokes the server action
- The action executes server-side
- The user is redirected to Stripe
This pattern eliminates the need for:
- Manual fetch/POST requests
- Client-side API key handling
- State management for loading states
- Error boundary setup (handled by Next.js)
Sources: app/page.tsx L5
Stripe SDK ConfigurationLink copied!
The action imports the stripe client from @/lib/stripe, which must be configured with the secret API key.
Stripe Client Initialization (Expected Pattern)
While the lib/stripe.ts file is not included in the provided code, it must export a configured Stripe client. Based on .env.example at .env.example L11
the expected configuration is:
| Environment Variable | Purpose |
|---|---|
STRIPE_SECRET_KEY | Server-side API key for creating sessions |
STRIPE_PUBLISHABLE_KEY | Client-side key (not used in this action) |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Public client-side key |
STRIPE_WEBHOOK_SECRET | For webhook signature verification (see Stripe Webhook Handling) |
The secret key must never be exposed to the client, which is why the checkout session creation happens in a server action rather than client-side code.
Sources: app/actions.ts L4
Error Handling ConsiderationsLink copied!
The current implementation at app/actions.ts L7-L33
does not include explicit error handling. If the Stripe API call fails, the error will propagate through Next.js's error boundary system.
Potential Error Scenarios
| Error Type | Cause | Behavior |
|---|---|---|
| Invalid API key | STRIPE_SECRET_KEY not set or incorrect | Stripe SDK throws error, Next.js shows error page |
| Network failure | Stripe API unreachable | Fetch timeout, error boundary activated |
| Invalid configuration | Malformed session parameters | Stripe API returns 400 error |
| Missing origin header | Edge case in origin detection | Uses localhost fallback |
The absence of try-catch blocks means errors are handled by Next.js's default error handling, which displays the error page (app/error.tsx if it exists, or default Next.js error UI).
For production systems, consider adding:
- Explicit error handling with user-friendly messages
- Logging to track failed checkout attempts
- Retry logic for transient network failures
- Validation of environment variables at startup
Sources: app/actions.ts L7-L33
Security ConsiderationsLink copied!
The server action pattern provides inherent security benefits:
| Security Feature | Implementation | Benefit |
|---|---|---|
| Server-side execution | "use server" directive | API keys never exposed to client |
| HTTPS enforcement | Vercel production environment | Protects session data in transit |
| No CSRF vulnerability | Next.js handles CSRF tokens automatically | Server actions include built-in protection |
| Origin validation | Uses origin header | Ensures redirects stay within app domain |
The redirect URLs constructed at app/actions.ts L26-L27
use the detected origin, ensuring users are redirected back to the legitimate application domain and not a spoofed site.
However, the cancel URL query parameter (canceled=true) is not currently validated or used, presenting a minor XSS consideration if future code displays this parameter without sanitization.
Sources: app/actions.ts L1
Correlation with Downstream SystemsLink copied!
The session_id generated by Stripe serves as the primary correlation key linking payment to repository access. This ID flows through multiple systems:
session_id Propagation Flow
The session_id enables manual correlation between:
- Payment records in Stripe Dashboard
- GitHub connection events in Vercel logs
- Automation trigger notifications in ntfy.sh
This correlation is essential because the system has no database—all correlation happens through log inspection. See Data Flow & Correlation for the complete correlation strategy.
Sources: app/actions.ts L26
Related ConfigurationLink copied!
The checkout session creation depends on several environment variables and external configurations:
| Configuration | Location | Purpose |
|---|---|---|
STRIPE_SECRET_KEY | .env file | Authenticates API requests |
NEXT_PUBLIC_APP_URL | .env file | Could be used for origin construction (not currently used) |
| Stripe Dashboard | External | Product catalog, webhook endpoint configuration |
| Vercel environment variables | Deployment platform | Production secret management |
See Environment Variables for complete configuration documentation.
Sources: .env.example L8-L14
Refresh this wiki
Last indexed: 23 November 2025 (922b35)
On this page
- Stripe Checkout Creation
- Purpose and Scope
- Overview
- Server Action Implementation
- Origin Detection and URL Construction
- Stripe Checkout Session Configuration
- Product Configuration Details
- Redirect URL Patterns
- Success URL Details
- Cancel URL Details
- Session Creation and Response Handling
- Integration with Landing Page
- Form Implementation Pattern
- Stripe SDK Configuration
- Error Handling Considerations
- Security Considerations
- Correlation with Downstream Systems
- Related Configuration
Ask Devin about godeep.wiki-jb