Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion browsers/payments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ agentcard uses an integration-specific alternative: the agent enters non-sensiti
5. invoke KERNEL's advertised `fill` operation to inject payment fields without supplying their values, then inspect the outcomes before submitting. for agentcard's alias-based flow, enter aliases and keep a trusted approval observer running while the checkout request is held.
6. submit checkout once, complete any remaining provider-hosted approval, and reconcile with the merchant's order state. fill or approval alone is not payment success.

`wallet` and `card` are vault item types. the wallet supplies the provider connection; the card represents payment material and its authorization state. retrieve the item and check `available_operations` before invoking an operation. don't assume every item supports `fill`.
`wallet` and `card` are vault item types. the wallet supplies the provider connection; the card represents payment material and its authorization state. where enabled for your organization, link and KERNEL purchases can also be `payment_request` items, which work like card items; agentcard purchases are always `card` items. retrieve the item and check `available_operations` before invoking an operation. don't assume every item supports `fill`.

```mermaid
%%{init: {"flowchart": {"nodeSpacing": 24, "rankSpacing": 28, "padding": 12}}}%%
Expand Down Expand Up @@ -56,6 +56,7 @@ your application must independently verify the merchant, items, amount, and curr

- [choose a wallet integration](/integrations/wallets/overview) for payment-method connection, approval, and reuse options.
- [KERNEL card](/integrations/wallets/kernel) to collect a user's card directly, with hosted or embedded enrollment.
- [KERNEL payment methods](/integrations/wallets/kernel-payment-methods) to hold several cards in one KERNEL wallet and choose which card pays.
- [enable payments in a browser agent](/browsers/enable-payments-in-browser-agent) for the controller, agent, and checkout walkthrough.
- [fill browser fields](/vaults/fill) for KERNEL's injection api, field selection, and outcome contract.
- [pricing](/info/pricing) for vault limits and payment charges.
1 change: 1 addition & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
"browsers/payments",
"integrations/wallets/overview",
"integrations/wallets/kernel",
"integrations/wallets/kernel-payment-methods",
"integrations/wallets/stripe-link",
"integrations/wallets/agentcard",
"integrations/wallets/embedded-card-capture",
Expand Down
1 change: 1 addition & 0 deletions info/api-key-permissions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Resources must be inside the new key's organization, or its project for a projec
| Any operation on an existing browser | The browser action, plus `profiles:use` on its attached profile and `vaults:use` on every linked vault. If the browser saves profile changes, `profiles:write` on that profile too. |
| Update a browser | `browsers:write` and `browsers:use`, plus `use` on any profile, vault, or proxy the update adds. |
| Fill from a vault | `vaults:use` on the vault and `browsers:use` on the browser. |
| Add or remove a card in a Kernel wallet (`add_payment_method`, `remove_payment_method`) | `vaults:use` and `vaults:write` on the vault. Without `vaults:write`, the wallet doesn't list either operation in `available_operations`, and invoking one returns `403` with `insufficient_scope`. Other wallet and purchase operations need only `vaults:use`. |
| Run a proxy health check | `proxies:use` and `proxies:read`. |

List endpoints return only the objects the key can access, so a key without a matching grant gets an empty list.
Expand Down
48 changes: 43 additions & 5 deletions integrations/wallets/embedded-card-capture.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ bun add @onkernel/vault-react

the package requires react 18 or later and ships no styles.

## Create the wallet on your backend
## Get a capture token on your backend

create the wallet from your authenticated backend, then read `action.capture_token` from the `card_enrollment` action. the token is a secret capability for this one wallet, not an api key.
read `capture_token` from a `card_enrollment` action in your authenticated backend. the token is a secret capability for one card enrollment, not an api key. where the action comes from depends on whether your organization has [payment methods](/integrations/wallets/kernel-payment-methods) enabled.

### Wallet with one card

create the wallet, then read `action.capture_token` from the wallet's `card_enrollment` action.

<CodeGroup>

Expand Down Expand Up @@ -75,6 +79,40 @@ if wallet.action is not None and wallet.action.name == "card_enrollment":

the wallet starts in `pending_authorization`. after the cardholder adds a card, it becomes `connected`.

### Wallet with payment methods

where payment methods are enabled, the wallet starts `connected` with no card and no action. invoke `add_payment_method` for each card, then read `payment_method.action.capture_token` from the result.

<CodeGroup>

```typescript TypeScript
const added = await kernel.vaults.items.performOperation("card-wallet", {
id_or_name: "user-12345",
type: "add_payment_method",
});

if (added.type === "add_payment_method") {
// return this to the cardholder's page only
const captureToken = added.payment_method.action?.capture_token;
}
```

```python Python
added = kernel.vaults.items.perform_operation(
"card-wallet",
id_or_name="user-12345",
type="add_payment_method",
)

if added.type == "add_payment_method" and added.payment_method.action is not None:
# return this to the cardholder's page only
capture_token = added.payment_method.action.capture_token
```

</CodeGroup>

the new payment method starts in `pending_enrollment`. after the cardholder adds a card, it becomes `active`.

## Render the component

deliver the token to the intended cardholder's page through your authenticated application, then render `KernelCardCapture`:
Expand Down Expand Up @@ -110,7 +148,7 @@ export function AddCard({ captureToken }: { captureToken: string }) {

| prop | description |
| ------------- | ------------------------------------------------------------------------------------------------------------ |
| `token` | the wallet's `action.capture_token` |
| `token` | the `capture_token` from the wallet's or payment method's `card_enrollment` action |
| `baseUrl` | api origin; defaults to `https://api.onkernel.com` |
| `className` | added to the root element, in both the form and completion views |
| `fieldCss` | css applied inside the card number, expiry, and cvc iframes |
Expand Down Expand Up @@ -244,7 +282,7 @@ wallet = kernel.vaults.items.retrieve(

</CodeGroup>

a `connected` wallet has a stored card. inspect the wallet's `payment_methods` before creating a purchase.
for a wallet with one card, `connected` means the card is stored. a wallet with payment methods is `connected` even before its first card, so retrieve it with the `payment_methods` expansion and check that the payment method you added is `active`. in both cases, inspect the wallet's `payment_methods` before creating a purchase.

## Handle errors

Expand All @@ -266,7 +304,7 @@ after `expired`, `unavailable`, or `unconfirmed`, the component removes the form

## Token lifetime

a `capture_token` lasts 30 minutes. when it expires, retrieve the wallet again from your backend; KERNEL returns a new `card_enrollment` action with a new `capture_token`. changing the component's `token` prop resets it.
a `capture_token` lasts 30 minutes. when it expires on a wallet with one card, retrieve the wallet again from your backend; KERNEL returns a new `card_enrollment` action with a new `capture_token`. for a wallet with payment methods, invoke `add_payment_method` again for a new payment method and token. changing the component's `token` prop resets it.

if the cardholder leaves the page after creating a card but before KERNEL confirms it, the component makes one best-effort attempt to resend the card as it unmounts or the page unloads. it ignores that request's result, so the card can still go unrecorded. always confirm the wallet's state from your backend, as described in [handle completion](#handle-completion).

Expand Down
Loading
Loading