> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waffo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SDKs

> Client libraries and framework integrations

## SDKs & Libraries

Waffo Pancake provides official SDKs for TypeScript and Next.js, plus direct API access.

### Choose Your Integration Level

<CardGroup cols={3}>
  <Card title="Next.js SDK" icon="react">
    **Fastest** — Drop-in components, hooks, and server actions. Handles checkout UI, webhook routing, and buyer self-service out of the box.

    `npm install @waffo/pancake-nextjs`
  </Card>

  <Card title="TypeScript SDK" icon="code">
    **Flexible** — Full API coverage with automatic signing, typed responses, and webhook verification. Use with any Node.js framework.

    `npm install @waffo/pancake-ts`
  </Card>

  <Card title="Direct API" icon="terminal">
    **Full control** — REST endpoints for writes, GraphQL for reads. Implement signing and verification yourself. Any language.
  </Card>
</CardGroup>

<Tip>
  **Next.js projects**: Start with `@waffo/pancake-nextjs` — it wraps `@waffo/pancake-ts` and adds React components and server actions. You can always drop down to the TypeScript SDK or raw API calls for advanced use cases.
</Tip>

***

## TypeScript SDK

<Card title="@waffo/pancake-ts" icon="npm" href="https://www.npmjs.com/package/@waffo/pancake-ts">
  Official TypeScript SDK on npm
</Card>

### Installation

```bash theme={"system"}
npm install @waffo/pancake-ts
```

### Features

* Zero runtime dependencies, ESM + CJS, Node >= 20
* Automatic request signing with deterministic idempotency keys
* Full TypeScript type definitions (15 enums, 40+ interfaces)
* Webhook verification with embedded public keys (test/prod)

### Quick Start

```typescript theme={"system"}
import { WaffoPancake } from "@waffo/pancake-ts";

const client = new WaffoPancake({
  merchantId: process.env.WAFFO_MERCHANT_ID!,
  privateKey: process.env.WAFFO_PRIVATE_KEY!,
});

// Create a store
const { store } = await client.stores.create({ name: "My Store" });

// Create a one-time product
const { product } = await client.onetimeProducts.create({
  storeId: store.id,
  name: "E-Book: TypeScript Handbook",
  prices: {
    USD: { amount: "29.00", taxIncluded: false, taxCategory: "digital_goods" },
  },
});

// Create a checkout session
const session = await client.checkout.createSession({
  productId: product.id,
  currency: "USD",
});
// => redirect consumer to session.checkoutUrl
```

### Configuration

| Parameter    | Type           | Required | Description                                             |
| ------------ | -------------- | -------- | ------------------------------------------------------- |
| `merchantId` | `string`       | Yes      | Your Merchant ID                                        |
| `privateKey` | `string`       | Yes      | RSA private key (PEM, base64, or raw — auto-normalized) |
| `baseUrl`    | `string`       | No       | API base URL (default: production)                      |
| `fetch`      | `typeof fetch` | No       | Custom fetch implementation                             |

### Available Resources

| Namespace                          | Methods                                            | Description                            |
| ---------------------------------- | -------------------------------------------------- | -------------------------------------- |
| `client.stores`                    | `create()` `update()` `delete()`                   | Store management                       |
| `client.onetimeProducts`           | `create()` `update()` `publish()` `updateStatus()` | One-time product CRUD                  |
| `client.subscriptionProducts`      | `create()` `update()` `publish()` `updateStatus()` | Subscription product CRUD              |
| `client.subscriptionProductGroups` | `create()` `update()` `delete()` `publish()`       | Product groups for shared trial        |
| `client.orders`                    | `cancelSubscription()`                             | Order management                       |
| `client.checkout`                  | `createSession()`                                  | Create checkout sessions               |
| `client.graphql`                   | `query<T>()`                                       | Typed GraphQL queries                  |
| `client.auth`                      | `issueSessionToken()`                              | Issue buyer session token for checkout |
| `client.webhooks`                  | `verify()`                                         | Webhook signature verification         |

### Checkout Modes

The SDK supports two checkout modes based on whether you know the buyer's identity:

| Mode              | Method                            | Buyer Identity    | Form       | Use Case                      |
| ----------------- | --------------------------------- | ----------------- | ---------- | ----------------------------- |
| **Authenticated** | `checkout.authenticated.create()` | Merchant provides | Pre-filled | Sites with user accounts      |
| **Anonymous**     | `checkout.anonymous.create()`     | Not provided      | Empty      | Template stores, shared links |

<Warning>
  **Always use authenticated checkout when you know the buyer.** Authenticated checkout binds orders to the `buyerIdentity` you provide — a stable, merchant-controlled identifier. Without it:

  * **Trial abuse**: buyers can claim unlimited free trials by changing their email
  * **Order unlinking**: different emails are treated as different users
  * **No self-service**: buyers cannot manage orders in Customer Portal
</Warning>

#### Authenticated Checkout (Recommended)

```typescript theme={"system"}
const result = await client.checkout.authenticated.create({
  productId: "PROD_xxx",
  currency: "USD",
  buyerIdentity: "userIdInYourSystem",
});
// Redirect: res.redirect(result.checkoutUrl) or window.location.href = result.checkoutUrl
```

<Note>
  `buyerIdentity` is for order attribution and trial tracking only — it is not rendered on the checkout page. To pre-fill the email field on the checkout form, pass `buyerEmail` explicitly.
</Note>

With dynamic pricing and trial control:

```typescript theme={"system"}
const result = await client.checkout.authenticated.create({
  productId: "PROD_xxx",
  currency: "USD",
  buyerIdentity: "userIdInYourSystem",
  buyerEmail: "customer@example.com",
  priceSnapshot: { amount: "19.99", taxCategory: "digital_goods" },
  withTrial: true,
  billingDetail: { country: "US", isBusiness: false },
  successUrl: "https://example.com/thank-you",
});
```

#### Anonymous Checkout

```typescript theme={"system"}
const result = await client.checkout.anonymous.create({
  productId: "PROD_xxx",
  currency: "USD",
});
// Also supports priceSnapshot and withTrial
```

### Webhook Verification

```typescript theme={"system"}
import { verifyWebhook, WebhookEventType } from "@waffo/pancake-ts";

// Express (use raw body — parsed JSON breaks signature verification)
app.post("/webhooks", express.raw({ type: "application/json" }), (req, res) => {
  try {
    const event = verifyWebhook(
      req.body.toString("utf-8"),
      req.headers["x-waffo-signature"] as string,
    );
    res.status(200).send("OK");

    switch (event.eventType) {
      case WebhookEventType.OrderCompleted:
        // handle order completion
        break;
      case WebhookEventType.SubscriptionActivated:
        // handle subscription activation
        break;
    }
  } catch {
    res.status(401).send("Invalid signature");
  }
});

// Next.js App Router
export async function POST(request: Request) {
  const body = await request.text();
  const sig = request.headers.get("x-waffo-signature");
  try {
    const event = verifyWebhook(body, sig);
    // handle event ...
    return new Response("OK");
  } catch {
    return new Response("Invalid signature", { status: 401 });
  }
}
```

### Error Handling

```typescript theme={"system"}
import { WaffoPancakeError } from "@waffo/pancake-ts";

try {
  await client.stores.create({ name: "" });
} catch (err) {
  if (err instanceof WaffoPancakeError) {
    console.log(err.status);  // 400
    console.log(err.errors);  // [{ message: "...", layer: "store" }, ...]
  }
}
```

***

## Next.js SDK

<Card title="@waffo/pancake-nextjs" icon="npm" href="https://www.npmjs.com/package/@waffo/pancake-nextjs">
  Official Next.js SDK — components, hooks, and server actions
</Card>

### Installation

```bash theme={"system"}
npm install @waffo/pancake-nextjs
```

Requires `@waffo/pancake-ts` as a peer dependency. Works with Next.js 14+ App Router.

### Client Exports

| Export                       | Type          | Description                                                    |
| ---------------------------- | ------------- | -------------------------------------------------------------- |
| `CheckoutButton`             | Component     | Three-mode checkout button (link / anonymous / authenticated)  |
| `WaffoPancakeProvider`       | Component     | Buyer self-service context with automatic token lifecycle      |
| `useCheckout()`              | Hook          | Programmatic checkout control                                  |
| `useBuyer()`                 | Hook          | Buyer self-service actions (cancel, refund, reactivate, query) |
| `useBuyerOrders()`           | Hook          | Fetch buyer's orders                                           |
| `useBuyerPayments()`         | Hook          | Fetch buyer's payment records                                  |
| `useBuyerRefundTickets()`    | Hook          | Fetch buyer's refund tickets                                   |
| `useMerchantOrders()`        | Hook          | Merchant dashboard orders                                      |
| `useMerchantSales()`         | Hook          | Merchant sales overview                                        |
| `useMerchantSubscriptions()` | Hook          | Merchant subscription overview                                 |
| `Webhook`                    | Route Handler | Auto-verify signatures and dispatch events                     |

### Server Exports (`@waffo/pancake-nextjs/server`)

| Export                              | Description                                  |
| ----------------------------------- | -------------------------------------------- |
| `createCheckoutAction(config)`      | Server Action: create checkout sessions      |
| `createBuyerTokenAction(config)`    | Server Action: issue buyer session tokens    |
| `createBuyerSessionAction(config)`  | Server Action: buyer self-service operations |
| `createMerchantQueryAction(config)` | Server Action: merchant GraphQL queries      |

### Quick Example

```typescript theme={"system"}
// app/lib/actions.ts
"use server";
import { createCheckoutAction, createBuyerTokenAction } from "@waffo/pancake-nextjs/server";

const config = {
  merchantId: process.env.WAFFO_MERCHANT_ID!,
  privateKey: process.env.WAFFO_PRIVATE_KEY!,
};

export const checkoutAction = createCheckoutAction(config);
export const issueBuyerToken = createBuyerTokenAction(config);
```

```tsx theme={"system"}
// app/components/BuyButton.tsx
"use client";
import { CheckoutButton } from "@waffo/pancake-nextjs";
import { checkoutAction } from "@/app/lib/actions";

export function BuyButton({ productId }: { productId: string }) {
  return (
    <CheckoutButton
      type="authenticated"
      action={checkoutAction}
      productId={productId}
      currency="USD"
      buyerIdentity={user.email}
    >
      Subscribe Now
    </CheckoutButton>
  );
}
```

### Webhook Route Handler

```typescript theme={"system"}
// app/api/webhooks/waffo/route.ts
import { Webhook } from "@waffo/pancake-nextjs";

export const POST = Webhook({
  onOrderCompleted: async (event) => {
    // Deliver digital goods
  },
  onSubscriptionActivated: async (event) => {
    // Provision access
  },
  onSubscriptionCanceled: async (event) => {
    // Revoke access
  },
});
```

<Card title="Next.js Guide" icon="code" href="/integrate/nextjs">
  Full step-by-step Next.js integration guide.
</Card>

***

## Direct API Access

You can also use the REST and GraphQL API directly. API Key authentication is handled automatically by the SDK -- no manual header setup is needed.

```typescript theme={"system"}
// Create a product
const { product } = await client.onetimeProducts.create({
  storeId: "your-store-uuid",
  name: "My Product",
  prices: {
    USD: { amount: "29.00", taxIncluded: false, taxCategory: "saas" },
  },
});

// Query data via GraphQL
const data = await client.graphql.query<{ stores: Array<{ id: string; name: string; status: string }> }>(
  `{ stores { id name status } }`
);
```

***

## SDK Roadmap

| Language                 | Status                                                                                     |
| ------------------------ | ------------------------------------------------------------------------------------------ |
| **Node.js / TypeScript** | Available — [`@waffo/pancake-ts`](https://www.npmjs.com/package/@waffo/pancake-ts)         |
| **Next.js**              | Available — [`@waffo/pancake-nextjs`](https://www.npmjs.com/package/@waffo/pancake-nextjs) |
| **Python**               | Planned                                                                                    |
| **Go**                   | Planned                                                                                    |
| **PHP**                  | Planned                                                                                    |

***

## Framework Guides

<CardGroup cols={2}>
  <Card title="Next.js" icon="code" href="/integrate/nextjs">
    Build with Next.js and Server Actions.
  </Card>

  <Card title="Checkout Sessions" icon="cart-shopping" href="/guides/checkout-session">
    Create checkout flows programmatically.
  </Card>

  <Card title="Subscriptions" icon="repeat" href="/guides/subscriptions">
    Implement recurring billing.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/integrate/webhooks">
    Receive real-time event notifications.
  </Card>
</CardGroup>

***

## API Reference

For complete endpoint documentation:

<Card title="API Reference" icon="book" href="/api-reference/introduction">
  Full REST and GraphQL API documentation.
</Card>
