# Agent Self-Setup Guide: Teach Yourself to Use Payjent

Audience: any agent reading this page directly.

Canonical URL: `https://payjent.com/docs/agent-payjent-self-setup.md`

## What Payjent is

Payjent is a spend control and payment gate for agent actions.

It helps an agent turn premium work into a human-approved task budget, wait for execution readiness, auto-resume the stored request after payment, and request a refund by default when paid downstream execution fails.

When a user asks you for premium work, Payjent lets you:

1. Create a paid action for that exact user request.
2. Send the user a Payjent payment link.
3. Wait for Payjent to verify payment.
4. Resume the exact stored request after payment.
5. Execute the downstream premium action in your own runtime.
6. Mark the Payjent action fulfilled.

Payjent can also perform a narrow verified fulfillment callback / execution handoff for premium actions that explicitly set `payjent_fulfillment_callback=true` (`payjent_managed_execution=true` remains a legacy alias). Payjent validates the callback target before it creates checkout; production deployments must set `PAYJENT_MANAGED_EXECUTION_ALLOWED_HOSTS` to the permitted fulfillment callback/executor hostnames. After Stripe confirms payment, Payjent sends one sanitized `POST` handoff callback to the stored `service_url` using the stored body only if it contains no reserved Payjent grant/payment/receipt/token fields, plus a small outbound header allowlist. The downstream provider/executor performs the premium action; Payjent records a fulfillment event and still preserves callback/polling flows. Mock/local payments do not run fulfillment callbacks in production.

Payjent is **not** a pay.sh settlement provider or the premium action executor. For pay.sh/paycurl work without `payjent_fulfillment_callback=true`, Payjent authorizes and resumes the request; you execute pay.sh externally after Payjent says the action is paid.

## Discovery flow: learn available paid tools

Before creating paid actions, discover what this Payjent instance supports:

1. Fetch the public manifest: `GET /.well-known/payjent-tools.json`. This is safe for any agent/client and contains no credentials, grants, or payment tokens. It describes Payjent tools, docs, auth requirements, and the authenticated capabilities URL.
2. If you have been installed with a private Payjent credential, call `GET /api/v1/agent-capabilities` with `X-Payjent-Bot-Key` from your private secret store.
3. Use the capabilities response to decide which paid actions and rails are available for your current agent. For example, generic paid actions may be available while x402 spend authorization depends on an enabled x402 rail.
4. Optionally read `GET /api/v1/payment-readiness` for non-secret deployment status booleans. In production, Stripe Checkout is the intended active payment rail when configured; readiness reports booleans only and never returns secret values.

Never ask a user to paste `X-Payjent-Bot-Key`, grants, payment tokens, deployment secrets, or install-link redemption output in chat.

### Premium tool discovery quickstart

Use this decision recipe when the user asks for premium provider work:

```text
GET /.well-known/payjent-tools.json
if installed: GET /api/v1/agent-capabilities with your private Payjent credential
GET /api/v1/premium-action-presets
choose a preset id from premium_tool_discovery.recommended_premium_paths
obtain the exact provider quote in your own runtime
POST /api/v1/premium-action-presets/{preset_id}/actions with exact amount_minor, matching cost_breakdown, request_hash, bot_id, external_user_id, and input
send only the returned payment/status link to the user
poll/resume after payment with the original request binding
execute the provider call in your own agent runtime using agent-side private provider credentials
complete the Payjent action, or fail it and request/refuse refund based on the provider outcome
```

The manifest and authenticated capabilities both expose `premium_tool_discovery`, including `premium_action_presets_url`, `premium_action_preset_count`, `agent_next_steps`, `creation_template`, and recommended premium paths grouped by provider/use case. Use actual preset ids from that block, such as `exa.deep_search`, `firecrawl.scrape`, `elevenlabs.text_to_speech`, `perplexity.sonar_search`, `replicate.prediction`, or `browserbase.screenshot`.

Payjent stores safe payment-gated envelopes only. Payjent does not execute provider API calls, does not need provider secrets, and must not receive provider authorization headers, cookies, API keys, private keys, or tokens. Provider credentials stay in the agent-side private runtime. Always obtain an exact provider quote first; if the exact price is unknown, do not create the Payjent action yet.

### FAL image generation default

For normal FAL image requests, prefer toolbox tool `fal.image.generate`. It is the canonical Payjent-managed FAL path and should be treated as the default/recommended route in discovery metadata.

Do not use `paysh.fal_image` for ordinary FAL image generation. It is an advanced external pay.sh/x402 fallback only; requests to quote, checkout, or create executions for it must include `external_runtime: true` in `arguments`, otherwise Payjent returns `422` guidance to use `fal.image.generate`.

## Primary setup flow: one-time Agent Install Link

Use the dashboard-created **Agent Install Link** as the primary setup flow:

1. The human owner signs in to the Payjent dashboard.
2. The owner registers the target agent identity.
3. The owner generates a short-lived, one-time Agent Install Link for that one agent.
4. The owner gives that private install link to the target agent.
5. The agent redeems the link exactly once and stores the returned agent-scoped credential privately.

The install link is a bearer setup secret, but it is scoped, short-lived, and single-use. It is safer than asking a human to paste raw credentials, tokens, or environment-variable lines in chat. If you receive an Agent Install Link, redeem it once from your secure runtime and do not repeat it in public conversation.

## Your rule

If a user asks you to use Payjent, do not ask them for code snippets, environment variables, Payjent agent ids, private credentials, grants, or raw payment tokens in chat.

You should instead ask the operator to authorize you in Payjent and give you a one-time Agent Install Link, or use dashboard/platform connections, a platform secret store, vault, or bot configuration page. The human should authorize you there; your platform or Payjent should store any private credential outside the conversation.

## Readiness states

### 1. Learning-ready

You are learning-ready if you can read this document and understand the flow.

In this state you may say:

> I know how Payjent works: I create a payment-gated action, send the user the Payjent payment link, poll or wait for Payjent readiness with my agent credential, resume the request, run the downstream premium action externally, and mark fulfillment.

You are **not** execution-ready yet unless you also have an agent credential.

### 2. Execution-ready

You are execution-ready only if Payjent or your platform has already stored a Payjent agent credential in your own secure tool/secret store.

Do not ask the user to paste raw secrets, Payjent agent ids, `.env` lines, or private credentials into chat. Prefer the Payjent dashboard authorization flow, a platform secret store, vault, or bot configuration page.

When you have a credential, remember it as a private tool credential, not as public conversation text. If you do not have one, say you are not connected and ask the operator to authorize you in Payjent; do not invent variable names or manual shell steps.

### 3. Paid-action-ready

You are paid-action-ready when you can make authenticated HTTPS requests to Payjent and store a pending action id between turns.

You need to be able to store:

- `action_id`
- `payment_session_id`
- `request_hash`
- the requesting user's id
- the requested downstream provider/action details

Do **not** store or reveal raw grant ids or payment tokens in public chat.

## What to do when a user asks for premium work

### Step 1: Decide whether Payjent is needed

Use Payjent only when the requested action requires payment before execution, such as a premium data/API call, paid pay.sh action, paid MCP tool, or spend-authorized agent action.

If the task is free, do not create a Payjent action.

### Step 2: Create a Payjent paid action

Before creating any Payjent paid action, first obtain the exact provider/merchant quoted price for the requested work. The `amount_minor` and `cost_breakdown` you send to Payjent must match that exact quote plus any optional transparent operator fee line items. Do **not** use placeholder, default, demo, test, minimum/top-up, hidden, or silently injected amounts such as `$1.00` or `100` minor units. If the exact price is unknown, fail closed: do not create the paid action yet, and tell the user, "Payjent is awaiting an exact provider quote before I can create the paid action."

Operator fee policy for this slice:

- Operator fees are optional; Payjent adds no default or hidden fees for existing agents.
- Any operator fee must be an explicit `cost_breakdown` line item, labeled separately from provider/merchant prices (for example, `agent operator fee`, `operator fee`, `service fee`, or `agent fee`).
- `amount_minor` must equal the provider/merchant exact quote plus those explicit operator fee line items. Payjent fails closed when the total and breakdown mismatch.
- Operator fees are not provider prices; do not bury them in the provider quote label.
- This only records transparent allocation metadata today. Future settlement/payout is ledgered separately and is not automated by this setup step.

Create a paid action with:

- your agent id
- the user's id
- a concise request summary
- exact quoted amount and currency, including any explicit operator fee line items
- matching `cost_breakdown` that sums to `amount_minor`
- downstream provider metadata, such as `provider=pay_sh`
- the target service or resource
- method/body if applicable
- for a Payjent verified fulfillment callback / execution handoff after Stripe payment only: `payjent_fulfillment_callback=true` (`payjent_managed_execution=true` legacy alias), a `POST` `service_url` whose hostname is allowed by the Payjent deployment, no reserved Payjent grant/payment/receipt/token fields anywhere in the body, and only supported outbound headers (`Content-Type`, `Accept`, `Idempotency-Key`, `X-Request-Id`, `X-Payjent-Action-Id`)

For pay.sh-style actions, the action should produce an execution envelope with:

- `provider=pay_sh`
- `settlement=external_pay_sh_runtime`
- a `command_preview` or equivalent execution description

### Step 3: Send the payment prompt to the user

Send only the returned Payjent `payment_prompt`/`payment_url`, the public status link `/status/{payment_session_id}`, and a short explanation. If Payjent is configured with Stripe Checkout, the URL may be a Stripe-hosted checkout link or a Payjent page with a “Continue to secure payment” button; send it as returned and do not modify it.

Good user message:

> Payment is required for this premium action. Pay here: `<Payjent payment link>`. You can track public status here: `<Payjent public status link>`. After payment, return to this chat and paste: `I paid for Payjent session <payment_session_id>; please check status and resume the exact approved action.`

After the user returns, poll/check Payjent with your private credential, verify the paid status and request binding, then execute the downstream provider action externally in your own runtime unless the action explicitly uses Payjent's verified fulfillment callback.

Do not send grant ids. Do not ask the user to paste a payment token.

### Step 4: Wait for payment

Use your private Payjent credential to check the paid action status.

Before payment, Payjent should report a waiting/unpaid state and should not reveal a payment token.

After payment, Payjent may return readiness to your authenticated agent runtime. Treat any returned payment token/grant as private execution material. Never show it to the user.

### Step 5: Resume exactly the paid request

When Payjent says the action is paid, resume/start the action using:

- the original action id
- the original user id
- the original request hash/presentation

If these do not match, stop. Do not execute the downstream action.

### Step 6: Execute downstream externally

If the execution envelope says `provider=pay_sh`, run the pay.sh/paycurl work in your own runtime after Payjent authorizes the action.

Payjent does not execute pay.sh for you. For x402/pay.sh paid APIs, after consuming the grant call `payjent.authorize_x402_spend` with `capture=true` for the exact quoted budget, then execute the gateway call externally (for example with `pay curl`/pay.sh) and mark the action complete.

Generic x402/pay.sh primitive: use `payjent.create_x402_paid_action` (`POST /api/v1/premium-actions/x402`) for any x402/pay.sh-compatible paid URL after you have already obtained the exact provider quote. The payload accepts `bot_id`, `external_user_id`, `request_summary`/`request_hash`, exact `amount_minor`/`currency`/`cost_breakdown`, `target_url` or `service_url`, `method`, safe non-secret `headers`, `body`, optional `service_fqn`/`resource`, and optional provider/rail metadata. Payjent validates and stores the envelope, creates a Stripe/Payjent payment session, binds the grant to the exact request hash, and returns a `command_preview` plus `execution_boundary=agent_executes_after_spend_authorization`. Payjent never posts the target URL and must not store Authorization, Cookie, API key, token, or secret headers.

Exact generic flow:

1. The agent obtains the exact x402/pay.sh quote from the provider/catalog first. If the amount is unknown, fail closed and do not create the Payjent action.
2. `POST /api/v1/premium-actions/x402` with the exact amount and matching cost breakdown.
3. Send only the returned Payjent payment prompt/URL to the user.
4. Poll `GET /api/v1/agent-actions/{action_id}` or wait for a safe callback until status is ready.
5. Consume the request-bound grant with the original `bot_id`, `external_user_id`, and `request_hash`.
6. Call `payjent.authorize_x402_spend` (`POST /api/v1/grants/{grant_id}/spend-authorizations`) for the exact action budget, usually with `rail=x402` and `capture=true`.
7. Execute `target_url`/`service_url` externally in the agent runtime with its x402/pay.sh tooling, then mark the Payjent action complete with non-secret provider receipt/job metadata.

BigQuery is only an example/backward-compatible preset over the generic primitive, not a bespoke Payjent product model. `payjent.create_bigquery_paid_query` (`POST /api/v1/premium-actions/pay-sh/bigquery-query`) creates a pay.sh action for the public catalog service `solana-foundation/google/bigquery`, resource `jobs`, gateway `https://bigquery.google.gateway-402.com/bigquery/v2`, endpoint `POST /projects/{project_id}/queries`. The preset stores `service_url=https://bigquery.google.gateway-402.com/bigquery/v2/projects/{project_id}/queries`, `method=POST`, `body={"query": "...", "useLegacySql": false}`, `provider=pay_sh`, and `payjent_execution_boundary=agent_executes_after_spend_authorization`. Payjent only gates Stripe payment and records/captures spend authorization; the agent executes BigQuery through pay.sh externally after authorization.

Example preset payload after obtaining the exact pay.sh/x402 quote:

```json
{
  "bot_id": "your-agent-bot-id",
  "external_user_id": "user-123",
  "project_id": "my-gcp-project",
  "query": "SELECT 1 AS ok",
  "use_legacy_sql": false,
  "request_summary": "Run exact paid BigQuery query through pay.sh/x402",
  "request_hash": "stable-request-hash",
  "amount_minor": 250,
  "currency": "USD",
  "cost_breakdown": [{"label": "pay.sh BigQuery quoted x402 cost", "amount_minor": 250}]
}
```

Do not use placeholder pricing; if the exact pay.sh/x402 quote is unknown, do not create the action yet.

### Step 7: Mark fulfillment

After execution, mark the Payjent action fulfilled with status and non-secret metadata.

If execution fails, mark it failed with a safe error summary.

## What not to do

Never:

- ask the user to paste a `grant_*` token
- expose raw payment tokens in chat
- claim Payjent executed pay.sh
- claim live settlement unless the downstream provider actually verified it
- reuse one user's paid authorization for another request
- resume an action if the user id or request hash does not match
- treat a public payment page as proof that you are authorized to execute

## If you are not configured yet

If you do not have a Payjent agent credential, say this:

> I can use Payjent, but I am not connected yet. Please open the Payjent dashboard, register/authorize this agent, and let Payjent or the platform store the private credential for me. Do not paste Payjent ids, credentials, grants, tokens, `.env` lines, or shell commands into chat.

Then wait for the operator or your platform to provide the credential through a secure channel.

Do not provide a manual `.env` recipe unless the operator explicitly asks for an unsafe manual fallback. Even then, never ask them to paste the resulting id, credential, grant, or token back into chat.

## Minimal mental model

Remember this sequence:

```text
premium user ask
→ create Payjent paid action
→ send payment link
→ Payjent verifies payment
→ agent privately resumes exact request
→ agent executes downstream premium provider externally
→ agent marks fulfilled
```

## Payjent public base URL

Use this Payjent deployment unless the operator gives you a different one:

`https://www.payjent.com`

## Current integration status

Payjent already supports the generic agent bridge. You do not need to know the Python code to follow the protocol, but the implementation name is:

- `AgentPayjentBridge`

Use the protocol above as your source of truth.

## Merchant purchase / procurement handoff (Amazon-style)

For Amazon-style purchases use `payjent.create_purchase_fulfillment` (`POST /api/v1/purchase-actions`) only when an allowlisted procurement executor is configured. Money flow is intentionally bounded: the human pays Stripe/Payjent; Payjent verifies payment and sends a signed, verified `POST` fulfillment callback to the allowlisted procurement executor; that executor buys from Amazon or the merchant using its own configured procurement/payment method (operator procurement service, virtual-card issuer, or merchant integration). Payjent does **not** send funds to the agent and does **not** directly pay Amazon unless the downstream executor/provider rail is the component doing that merchant payment.

Required purchase payload fields include exact `amount_minor`, `currency`, matching `cost_breakdown`, `merchant.name`, `merchant.domain`, `item.summary` and optional `item.url`, `order_summary`, `service_url`, `method=POST`, `body`, `headers`, and `payjent_fulfillment_callback=true`. Do not include or request Amazon credentials, account passwords, card numbers, CVV/CVC/PAN, shipping-address secrets, raw tokens, or private credentials in chat or in the fulfillment body. The downstream procurement executor must already have its own secure configuration for checkout/payment.

Example after researching an Amazon item and obtaining the exact merchant quote:

```json
{
  "bot_id": "your-agent-bot-id",
  "external_user_id": "user-123",
  "request_summary": "Purchase exact quoted Amazon item via configured procurement executor",
  "amount_minor": 4299,
  "currency": "USD",
  "cost_breakdown": [{"label": "Amazon quoted total", "amount_minor": 4299}],
  "merchant": {"name": "Amazon", "domain": "amazon.com"},
  "item": {"summary": "Exact item title, quantity 1", "url": "https://www.amazon.com/dp/EXAMPLE"},
  "order_summary": "Buy quantity 1 at the exact quoted total; no substitutions unless executor policy permits.",
  "service_url": "https://procurement-executor.example/purchase-handoffs",
  "method": "POST",
  "body": {"merchant": "amazon.com", "item_url": "https://www.amazon.com/dp/EXAMPLE", "quantity": 1, "quoted_total_minor": 4299, "currency": "USD"},
  "headers": {"Content-Type": "application/json"},
  "payjent_fulfillment_callback": true
}
```

Fail closed if there is no procurement executor allowlist/configuration or the exact merchant quote is unavailable: do not create a payment link, and tell the user Payjent is awaiting an exact merchant quote or configured procurement executor.
