Skip to content

Embedded checkout SDK, businesses CLI fixes, paywall demo app - #48

Merged
PancheI merged 16 commits into
mainfrom
feat/embedded-checkout-sdk
Sep 29, 2026
Merged

PancheI merged 16 commits into
mainfrom
feat/embedded-checkout-sdk

Conversation

@PancheI

@PancheI PancheI commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

What this is

  • @agentaos/checkout: the embeddable checkout (/v1/agentaos.js script, loadAgentaOS, AgentaOS.checkout.open, React <AgentaOSCheckout> and useAgentaOSCheckout), with tests.
  • CLI: businesses group fixes (--no-invite-email, --no-email spelled as promised), plus the businesses/verify/discount commands wired to the platform's Connect endpoints.
  • examples/paywall-demo: a runnable paywall for logged-in users (Express + @agentaos/pay): checkout with the user's id in metadata, success page that reads the checkout, webhook that unlocks and matches renewals by the stored subscription id, once-per-session unlocking, access check, the user's invoices with PDF and receipt, cancel at period end, upgrade from a quote; a script that posts signed sample events. Run end to end against the API in test mode. Documented under SDK → Recipes on the docs site.
  • Hygiene: example addresses on example.com.

Checks: pay 144, checkout 15, wallet 260, mcp-remote 11 tests green; secrets/PII sweep clean; .env, data and certificates ignored.

Notes

  • Depends on the platform's feat/connect (PR #206) for the businesses endpoints.
  • The lockfile also carries pnpm's cooldown re-resolution of ws 8.21.0 → 8.18.3 under the langchain/openai entries.
  • Local-dev defects found by the demo (platform side): success URLs refuse localhost even in test mode; webhooks are not delivered to private addresses.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1

PancheI and others added 16 commits September 14, 2026 15:03
Three ways to sell a subscription that the API already does and the SDK and CLI
could not reach: a code the buyer types at checkout, credit the merchant puts on a
subscriber's account, and a trial that costs something instead of being free.

The credit's idempotency key is a REQUIRED parameter rather than one we generate.
There is no record of a credit on our side for the server to recognise a repeat by,
so a key minted per call would protect nothing - the retry would mint a second one
and credit the subscriber twice. Only the caller knows whether a second call is a
retry or a second deliberate credit, so only the caller can supply it. The CLI mints
one per invocation, which is the same rule read the other way: running the command
twice IS two credits, and it prints the key so a caller who must retry can repeat it.

The credit history is the one response that carries money without naming a currency,
so the CLI prints those figures bare rather than stamping a symbol the server never
sent. Everything else it shows is formatted straight from the response; it derives no
total and subtracts nothing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…as an overlay on your own page

A browser-only package beside the server SDK (@agentaos/pay): loadAgentaOS() loads
app.agentaos.ai/v1/agentaos.js once (SSR-safe, retries after a failed load), typed options and
events, and @agentaos/checkout/react with <AgentaOSCheckout> (inline; a changed link updates
the open checkout) and useAgentaOSCheckout() (overlay). No runtime dependencies; React is an
optional peer. README, a SKILL.md section and a changeset (minor). 12 tests; proven in a
browser against a local stack.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…d, retries never hang, 'use client'

Independent review of 4ed279b: the overlay hook took neither or both of link/session (a cast hid
it) — now CheckoutSource & behaviour, checked by the type; <AgentaOSCheckout> reports a failed
script load to onEvent as checkout.error not_loaded instead of an empty box; a load that brings
no AgentaOS removes its tag so a retry does not wait forever; react.tsx is 'use client' for the
Next.js App Router; the overlay never opens after its component unmounted. Docs: checkout.closed
also fires on close()/unmount, prefill and successUrl are read at open, the first origin wins,
redirects are https only and never for bank_transfer. 15 tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…, else the product's

For a server-created checkout the frame uses session.success_url ?? link.success_url,
so the checkouts.create successUrl wins. README, types and SKILL said "the product's".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…d on every call

Connect PRD §6.1 R9-2: sends AgentaOS-Account (Stripe's Stripe-Account /
stripeAccount). A per-call option wins over the client's.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…t codes, credits, trial price)

# Conflicts:
#	packages/pay/src/resources/subscriptions.ts
…ped with its business

PRD §6.1 R9-2: businesses list/retrieve/create/resendInvitation/revokeInvitation/
createVerificationLink; WebhookEvent lists all 12 server events, each with
business. Fix: 204 No Content resolves (revokeInvitation is the first DELETE).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
… tool

PRD §6.1 R9-3: six businesses operations rendered into the CLI and the MCP
server; every command and tool can act for a managed business (AgentaOS-Account).
Parity test holds both surfaces to the catalogue plus business.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
PRD §6.1 R9-4: the agent skill learns Connect (six tools, --business, the ID
check link only the client completes); the operations count is 31.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…hooks.verify returns them

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…t; it lives in the dashboard)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…ateless server has nothing to stream

A GET opened an SSE stream nobody writes to; the Worker tore it down, the client
reconnected at once — 21,000 requests an hour and the day's KV reads. 405 is the
spec's answer for a server with nothing to push; enableJsonResponse completes
each reply inside its request.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…s the platform by mistake

PRD §6.1 R9-3 (review finding): the Worker's client factory dropped `business`,
so a tool called for a managed business ran as the platform. Now forwarded;
tested end to end through handleMcp.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
…spelled as promised

The shared `--email <email>` value flag won over the invite command's on/off switch, so
`agenta businesses invite <id> --no-email` answered "unknown option" (PRD §6.1 R9-3). Both
invitation switches now have their own spelling and say what they do; the group help drops
the internal noun.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
A Notes app with a Pro plan on Express and the @agentaos/pay SDK: checkout
with the user's id in metadata, a success page that reads the checkout, a
webhook that unlocks Pro and matches renewals by the stored subscription
id, once-per-session unlocking, an access check, the user's invoices with
PDF and receipt, cancel at period end, upgrade from a quote; a script
that posts signed sample events to the webhook route. Run end to end
against the API in test mode. Documented on the docs site under
SDK → Paywall for logged-in users.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KdSgWa5Lf9mnHxY3x76Fy1
@PancheI
PancheI merged commit 32afd60 into main Sep 29, 2026
1 check passed
@PancheI
PancheI deleted the feat/embedded-checkout-sdk branch September 29, 2026 07:39
@github-actions github-actions Bot mentioned this pull request Sep 29, 2026
PancheI pushed a commit that referenced this pull request Sep 29, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @agentaos/checkout@0.1.0

### Minor Changes

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - New package: the
AgentaOS checkout on your own page — inline or overlay. `loadAgentaOS()`
loads the checkout script once (SSR-safe), typed options and events
(`checkout.loaded`, `checkout.completed`, `checkout.closed`,
`checkout.error`), and `@agentaos/checkout/react` with
`<AgentaOSCheckout>` and `useAgentaOSCheckout()`.
## @agentaos/pay@2.4.0

### Minor Changes

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - Connect — manage your
clients' businesses and act for them, the way Stripe Connect does.
Add
`businesses.list/retrieve/create/resendInvitation/revokeInvitation/createVerificationLink()`.
`create` invites your client as admin and returns `inviteUrl`; pass
`sendInvitationEmail: false` to send it yourself (white-label).
`createVerificationLink` is the identity check link only your client can
complete (Stripe's Account Links).
Act for a business with `new AgentaOS(key, { business })` or `{ business
}` as the last argument of any call — sent as `AgentaOS-Account`
(Stripe's `Stripe-Account`).
`WebhookEvent` now lists every event we send — adds `dispute.created`,
`dispute.closed`, `account.updated` and `webhook.test` — and each
carries `business`: the business it happened in.
  Fix: a call answered with 204 No Content resolves instead of failing.

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - Add
`discountCodes.create/list/get/archive()`: codes a buyer types at
checkout on a subscription plan, including tracking-only codes that
change no price and exist to record who a referral brought in.
`subscriptions.list({ discountCode })` filters by one, and every
`Subscription` now carries the `discount` it was bought with.
Add `subscriptions.credit(id, params)` and `subscriptions.credits(id)`:
credit against a subscriber's next invoice. `idempotencyKey` is a
required parameter, not an optional one — there is no local record of a
credit for the server to recognise a repeat by, so a retry without the
caller's own key credits twice.
Add `trialAmount` to `paymentLinks.create()` and to `PaymentLink`, so a
plan can sell a paid trial ("9 for the first 30 days, then 29 a month")
instead of only a free one.
## agentaos@3.2.0

### Minor Changes

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - Connect — `agenta
businesses list | get | create | invite | revoke-invite | id-link` for
the businesses you manage (your clients' businesses and your other
apps), and `--business <id>` on every command to act as one of them
(`agenta products create … --business <id>`). The MCP server has the
same six `agenta_businesses_*` tools and an optional `business` input on
every tool.

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - Six new operations, on
both the CLI and the MCP tools (25 in total): `discounts
create|list|show|archive` for codes buyers type at checkout, and
`subscriptions credit|credits` for credit against a subscriber's next
invoice. `subscriptions list --code` shows who one code brought in.
`products create --trial-amount` prices a trial, so a plan can sell "9
for the first 30 days, then 29 a month"; the created plan now says what
the trial costs before it renews.
The credit command mints one idempotency key per invocation and reports
it under `--json`, so running it twice is two deliberate credits while a
network retry inside one call is not.

### Patch Changes

- Updated dependencies
[[`32afd60`](32afd60),
[`32afd60`](32afd60)]:
  - @agentaos/pay@2.4.0
## @agentaos/chains@3.2.0

### Patch Changes

- Updated dependencies []:
  - @agentaos/core@3.2.0
## @agentaos/engine@3.2.0

### Patch Changes

- Updated dependencies []:
  - @agentaos/core@3.2.0
  - @agentaos/crypto@3.2.0
## @agentaos/sdk@3.2.0

### Patch Changes

- Updated dependencies []:
  - @agentaos/core@3.2.0
  - @agentaos/engine@3.2.0
## @agentaos/core@3.2.0


## @agentaos/crypto@3.2.0


## @agentaos/mcp-remote@0.1.2

### Patch Changes

- [#48](#48)
[`32afd60`](32afd60)
Thanks [@PancheI](https://github.com/PancheI)! - The hosted connector
answers GET with 405 and replies with plain JSON (a stateless server has
nothing to stream), and every tool passes `business` on, so a platform
acting for a managed business never runs as itself.

- Updated dependencies
[[`32afd60`](32afd60),
[`32afd60`](32afd60),
[`32afd60`](32afd60),
[`32afd60`](32afd60)]:
  - agentaos@3.2.0
  - @agentaos/pay@2.4.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant