---
name: knox-integrate
description: Self-integrate a fresh customer app or migrate an existing Stripe or other-processor application to Knox, preserving incumbent payments and proving the sandbox replacement.
---

# Integrate Knox payments

Test mode only. Live processing is disabled. Preserve the customer's existing payment provider and production traffic.
Knox implements a subset of Stripe operations, not every Stripe feature. Check supported operations before writing code.

## Detect the starting point and own the integration

The customer gives one request: integrate or migrate this app to Knox. Perform the code changes, tests and migration preparation yourself.
Inspect repository instructions and trace the actual payment path before choosing the workflow. Do not ask the customer to choose a pattern.
Optionally download and read https://docs.knoxapi.com/agent-setup/tools/preflight.py, then run it with Python against the repository.
It emits only file/line/provider signals, never source snippets or secret values. Treat its suggested workflow as a hint;
mixed processors, dynamic integrations and an apparent absence of SDKs still need application review.

- Fresh app: continue with the prescribed checkout below.
- Existing Stripe app: read https://docs.knoxapi.com/agent-setup/stripe-to-knox.md and apply that migration workflow.
- Another processor: read https://docs.knoxapi.com/agent-setup/processor-to-contract.md; build the Stripe-shaped contract,
  then continue into the shared Stripe-to-Knox workflow. Preserve the original processor as the incumbent arm.

All three paths converge on a verified Knox integration. Report incomplete capabilities and data migration explicitly.
Customer involvement supplies business facts, private account access and an authorized live migration policy; it is not manual code editing.

## Inspect and establish access

1. Read https://docs.knoxapi.com/llms.txt and https://docs.knoxapi.com/openapi/knox.json.
2. Inspect the repository's instructions, checkout flow, order totals/currency, fulfillment, framework and test commands.
   Work on a new branch and preserve unrelated changes. Ask for unknown business mappings; never guess an amount or currency.
3. Use an existing authorized workspace. Customer login: https://dashboard.knoxapi.com/login.
   New test-mode accounts are self-serve at https://dashboard.knoxapi.com/register where sign-up is enabled; otherwise
   an operator-issued invite is required.
   Read `KNOX_SECRET_KEY`, `KNOX_PUBLISHABLE_KEY` and `KNOX_WEBHOOK_SECRET` from the customer's environment or secret store.
   If `KNOX_SECRET_KEY` and `KNOX_PUBLISHABLE_KEY` are not set, get test keys with either option below.
   Never ask the customer to paste secrets into the conversation. Do not print, commit, log, or put them in fixtures.
   The server key must be a test key, `sk_test_` (secret) or `rk_test_` (restricted), and the publishable key `pk_test_`;
   refuse live keys for this workflow. `KNOX_SECRET_KEY` names the server key whichever kind it is.
   The secret and publishable keys are needed before payment calls. The webhook signing secret may not exist yet:
   register the endpoint in the webhook step, store its newly returned secret privately, then configure verification.
   If an entry needed for the current step is missing, explain what must be supplied privately and stop only dependent steps.

### Get test keys

Option A, request keys through the API (preferred when the customer can open the dashboard). Ask the customer for the email
of their Knox account; do not guess it. Key requests are served by the Meta host, not the Stripe-compatible API host.

1. `POST https://meta.knoxapi.com/knox/v1/agent/key_requests` with `Content-Type: application/json` and
   `{"email", "agent_name", "repository"}`. `agent_name` is your product name (for example "Claude Code"); `repository` is the
   repository's `owner/name` or its directory name, not a URL. The call needs no credentials. The response is
   `{"id", "user_code", "verification_url", "expires_at", "interval"}`. The key will be named "Agent: <agent_name> (<repository>)".
2. Show the customer `user_code` (`KNX-XXXX-XXXX`) and `verification_url` exactly as returned. They sign in, open the link,
   type the code and click Approve. The email they receive contains the link but not the code.
3. Poll `GET https://meta.knoxapi.com/knox/v1/agent/key_requests/{id}` every `interval` seconds. `{"status":"pending"}` means keep
   waiting. HTTP 429 with `error.code` `slow_down` means wait `interval` seconds longer, then continue. Requests expire after 15 minutes.
4. On `{"status":"approved","secret_key","publishable_key","key_id"}` the keys are returned exactly once; if they are lost before
   they are saved, start a new request. Write them to an env file that git ignores, confirmed with `git check-ignore <file>`,
   or ask the customer where to store them. Never print, log or commit the secret key.
   `secret_key` is a restricted test key (`rk_test_`), not a full secret key. It may write `payment_intents`, `payment_methods`,
   `customers`, `charges` (which covers refunds) and `webhook_endpoints`, read `events` and `integration_status`, read the traffic ramp and post traffic
   observations: every call in this guide and the Stripe migration workflow. Any other call answers HTTP 403
   (`invalid_request_error`, code `more_permissions_required`, "Enabling <Label> <Read|Write> ('<permission>') permissions on
   this key would allow this request to continue"; `<permission>` is the resource in the singular, e.g. `charge_read`).
   If the application needs such a call, tell the customer which permission is missing and ask for a restricted key that has it,
   created at https://dashboard.knoxapi.com/api-keys. Do not work around the 403. The scope limits which endpoints the key may call,
   not what they return: `expand` returns any object the response references (expanding `latest_charge` needs no `charges`
   permission), and events and webhook deliveries carry full objects of every type they cover, charges included.
5. On `denied`, `expired`, a 404 on poll, or a 429 `rate_limit` on create, stop and tell the customer what happened.
   Do not retry on your own.

Option A through MCP: if the customer runs Knox's local MCP server (https://docs.knoxapi.com/agent-setup/tools/knox-mcp.py),
`knox_request_test_keys` and `knox_poll_test_keys` perform these steps and write the keys to a git-ignored env file without
returning them; `knox_integration_spec`, `knox_preflight`, `knox_register_webhook`, `knox_test_payment` and
`knox_integration_status` cover the remaining steps for Express, Next.js, FastAPI and Django apps.

Option B, from the dashboard: the customer creates test keys at https://dashboard.knoxapi.com/api-keys (a secret key, or a
restricted key with the permissions the application needs) and supplies them privately through the environment or secret store.

## Implement the prescribed checkout flow

Install the official Stripe server SDK using the application's existing package manager and lockfile.
The Payments API base is https://api.knoxapi.com; Stripe SDKs append `/v1` themselves.
Knox serves the Stripe API versions 2026-03-25.dahlia, 2026-04-22.dahlia, 2026-05-27.dahlia, 2026-06-24.dahlia,
2026-07-29.dahlia and 2026-08-26.dahlia (the current one); llms.txt and openapi/knox.json carry the live list.
An SDK that pins one of them (stripe-python 15.6.1 sends 2026-08-26.dahlia) works as is. Do not pin an SDK to another
version for Knox: unsupported `Stripe-Version` values are being phased out to Stripe's 400. Register webhook endpoints
without `api_version`, or with one of these versions; any other value is refused.

```python
import os
import stripe
client = stripe.StripeClient(os.environ["KNOX_SECRET_KEY"], base_addresses={"api": "https://api.knoxapi.com"})
```

```javascript
const client = new Stripe(process.env.KNOX_SECRET_KEY, { host: "api.knoxapi.com", protocol: "https" });
```

1. On the server, authenticate the shopper, compute the amount from the stored order in minor units, and create a PaymentIntent.
   Set `metadata[order_id]`. Use a stable order/payment-attempt identifier as `Idempotency-Key` so retries do not charge twice.
   Return only the `client_secret` needed for confirmation. Keep the secret API key on the server.
2. Load the hosted browser SDK from https://api.knoxapi.com/js/v1/knox.js.
   Do not use Stripe.js for Knox: it contacts Stripe's servers. Knox browser packages are not assumed to be published on npm.
   Use the hosted SDK instead of inventing package installation commands.
   Mount Knox's hosted card fields with the publishable key; never build raw card inputs on the customer's origin.

```javascript
const knox = Knox(publishableKey, { apiBase: "https://api.knoxapi.com" });
const card = knox.elements().create("card");
card.mount("#knox-card");
const { paymentIntent, error } = await knox.confirmCardPayment(clientSecret, { payment_method: { card } });
```

3. Add a webhook route preserving the raw request body. Verify `Stripe-Signature` with the Stripe SDK and the endpoint's signing secret.
   Register the customer's reachable HTTPS URL with `POST https://api.knoxapi.com/v1/webhook_endpoints` for `payment_intent.succeeded`.
   Knox returns the signing secret at creation; store it privately as `KNOX_WEBHOOK_SECRET` without printing the API response.
   Fulfill the order only from a verified event, once per order, and acknowledge after the fulfillment is persisted.
   Verify order ownership, amount and currency against the stored order. Browser success alone is not fulfillment evidence.
4. If the application has refunds, add `POST /v1/refunds` using the PaymentIntent and verify the supported refund behavior.
   Keep PAN, CVC and real cardholder data out of the customer's server, logs, tests and source.
   Sandbox test helpers `pm_card_visa` and `pm_card_chargeDeclined` can test server operations; they do not prove browser confirmation.

## Verify before reporting completion

Run the application's tests, then perform a sandbox checkout through the mounted card frame and confirm that the signed webhook fulfills the order.
Use test card data only inside Knox's hosted sandbox frame, never in customer code or logs.
If the customer server cannot receive the webhook, report that missing step instead of claiming completion.

Query https://meta.knoxapi.com/v1/integration_status with the server-side test key (secret or restricted).
This Knox-specific verification endpoint belongs to Meta, not the Stripe-compatible API host.
Require `livemode: false`, `ready: true`, and every available check `passed`:
`secret_key_used`, `publishable_key_used`, `test_payment_succeeded`, `payment_confirmed_client_side`,
`webhook_endpoint_enabled`, `webhook_payment_succeeded_delivered`, `card_fields_mounted`.
The check reflects workspace-level evidence. Also verify this application's own test payment and fulfillment;
pre-existing activity in the workspace alone is not proof of the new integration.

Review the diff for credentials, raw card fields, unrelated changes and dependencies. Run any project secret scanner.
Create an integration report in the repository recording nonsecret mappings, changed files, test commands/results,
the test PaymentIntent/event identifiers and each readiness result. Redact client secrets and personal data.
Provide a reviewable branch/PR where the customer's instructions authorize publication; do not deploy or move live traffic.
Explain rollback and list incomplete checks explicitly. Routing configuration is a separate Meta Knox workflow.
