diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b4da64f2..4a1242df 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.132.0" + ".": "0.133.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bd749034..b10427eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.133.0](https://github.com/kernel/kernel-python-sdk/compare/v0.132.0...v0.133.0) (2026-10-27) + + +### Features + +* Support multiple Kernel wallet payment methods and payment requests ([99d8515](https://github.com/kernel/kernel-python-sdk/commit/99d851577f0ed2f7ba78849172f8fdddb0a9ce31)) + ## [0.132.0](https://github.com/kernel/kernel-python-sdk/compare/v0.131.0...v0.132.0) (2026-10-26) diff --git a/api.md b/api.md index ae4bb2bb..a2995e3a 100644 --- a/api.md +++ b/api.md @@ -569,6 +569,8 @@ Types: ```python from kernel.types.vaults import ( + AddPaymentMethodVaultItemOperationRequest, + AddPaymentMethodVaultItemOperationResult, AgentcardCheckoutAuthorization, AgentcardCheckoutPreparation, AgentcardPreparedProcessor, @@ -602,6 +604,7 @@ from kernel.types.vaults import ( KernelCredentialVaultItemSpec, KernelCredentialVaultItemSpecInput, KernelCredentialVaultItemState, + KernelPaymentRequestVaultItemSpec, KernelWalletState, KernelWalletVaultItemSpec, LinkShippingAddress, @@ -621,8 +624,13 @@ from kernel.types.vaults import ( OnePasswordRecoverVaultItemOperationRequest, OnePasswordRequestAccessVaultItemOperationRequest, PasskeyVaultItemOperationResult, + PaymentRequestVaultItem, + PaymentRequestVaultItemSpec, + PaymentRequestVaultItemState, PrepareCheckoutVaultItemOperationRequest, RegisterPasskeyVaultItemOperationRequest, + RemovePaymentMethodVaultItemOperationRequest, + RemovePaymentMethodVaultItemOperationResult, RestartVerificationVaultItemOperationRequest, VaultCardAliases, VaultCardFillField, diff --git a/pyproject.toml b/pyproject.toml index 2b17777b..bba5860d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "kernel" -version = "0.132.0" +version = "0.133.0" description = "The official Python library for the kernel API" dynamic = ["readme"] license = "Apache-2.0" diff --git a/src/kernel/_version.py b/src/kernel/_version.py index 2913ee42..720e7ab3 100644 --- a/src/kernel/_version.py +++ b/src/kernel/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "kernel" -__version__ = "0.132.0" # x-release-please-version +__version__ = "0.133.0" # x-release-please-version diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py index 0347d455..ad0db16c 100644 --- a/src/kernel/resources/vaults/items.py +++ b/src/kernel/resources/vaults/items.py @@ -34,6 +34,7 @@ from ...types.vaults.vault_webmcp_binding_param import VaultWebmcpBindingParam from ...types.vaults.vault_checkout_context_param import VaultCheckoutContextParam from ...types.vaults.vault_item_operation_response import VaultItemOperationResponse +from ...types.vaults.payment_request_vault_item_spec_param import PaymentRequestVaultItemSpecParam from ...types.vaults.credential_vault_item_spec_input_param import CredentialVaultItemSpecInputParam from ...types.vaults.credential_vault_item_spec_update_param import CredentialVaultItemSpecUpdateParam from ...types.vaults.one_password_credential_account_spec_param import OnePasswordCredentialAccountSpecParam @@ -177,6 +178,55 @@ def update( """ ... + @overload + def update( + self, + key: str, + *, + id_or_name: str, + spec: PaymentRequestVaultItemSpecParam, + type: Literal["payment_request"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItem: + """ + Credential updates require type credential and the current version, and change + only values or description; omitted values are preserved, nonempty strings + replace, and null or empty strings clear supported fields. Clearing required + text/email/password values returns pending_collection; browser forms still + require nonempty required inputs. Card updates may omit type for compatibility + with legacy requests. Requested cards accept a replacement specification. + Pending issuance requests may update provider-supported fields on their existing + request, subject to atomic provider approval checks; omitted optional fields + remain unchanged and explicit empty lists clear them. Wallet/provider binding + and unsupported fields cannot change after authorization starts. An uncertain + update enters recovery_required; delete the card and create a new one rather + than retrying the update. Checkout cards may be edited between authorizations. A + Link card authorized with browser_id and page_url cannot be changed; delete it + and create a new card with the updated details. + + Args: + spec: Live Link card request. Test-mode card creation is not supported. The spec can + be changed with PATCH until the card is authorized at a checkout. Authorize it + with the browser at final checkout: Kernel inspects the checkout through WebMCP + and internally chooses a merchant-bound Link Pay Token when supported or a + virtual card otherwise. Callers never receive or choose how the credential is + delivered. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload def update( self, @@ -228,14 +278,14 @@ def update( """ ... - @required_args(["id_or_name", "spec"], ["id_or_name", "spec", "type", "version"]) + @required_args(["id_or_name", "spec"], ["id_or_name", "spec", "type"], ["id_or_name", "spec", "type", "version"]) def update( self, key: str, *, id_or_name: str, - spec: CardVaultItemSpecParam | CredentialVaultItemSpecUpdateParam, - type: Literal["card"] | Literal["credential"] | Omit = omit, + spec: CardVaultItemSpecParam | PaymentRequestVaultItemSpecParam | CredentialVaultItemSpecUpdateParam, + type: Literal["card"] | Literal["payment_request"] | Literal["credential"] | Omit = omit, version: int | Omit = omit, expected_item_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -445,6 +495,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. The browser must have this vault attached. @@ -501,6 +557,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -559,6 +621,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: amount: Actual transaction amount in minor units, no greater than the approved limit. @@ -616,6 +684,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -668,6 +742,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: checkout: Required when preparing an unused AgentCard card for a supported checkout processor. Consent is bound to this browser and declared merchant origin, not a @@ -729,6 +809,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -801,6 +887,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -858,6 +950,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -916,6 +1014,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -975,6 +1079,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -1027,6 +1137,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -1082,6 +1198,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -1141,6 +1263,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -1194,6 +1322,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: access_token_expires_at: Optional supplied expiry. Omit to clear the old expiry. @@ -1253,6 +1387,12 @@ def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -1278,6 +1418,123 @@ def perform_operation( """ ... + @overload + def perform_operation( + self, + key: str, + *, + id_or_name: str, + type: Literal["add_payment_method"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize; pass browser_id and page_url from the final checkout + page so Kernel can inspect the checkout. Eligible unused AgentCard cards + advertise prepare_checkout, which requires checkout context and obtains device + approval before native Square Pay. Keep the returned approval page open, poll + until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Ready Kernel cards advertise fill. Fill delivers card details for a few minutes; + submit checkout promptly after filling. A repeated fill is safe. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + def perform_operation( + self, + key: str, + *, + id_or_name: str, + payment_method_id: str, + type: Literal["remove_payment_method"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize; pass browser_id and page_url from the final checkout + page so Kernel can inspect the checkout. Eligible unused AgentCard cards + advertise prepare_checkout, which requires checkout context and obtains device + approval before native Square Pay. Keep the returned approval page open, poll + until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Ready Kernel cards advertise fill. Fill delivers card details for a few minutes; + submit checkout promptly after filling. A repeated fill is safe. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + + Args: + payment_method_id: ID from the wallet's payment_methods expansion. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args( ["id_or_name", "type"], ["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"], @@ -1286,6 +1543,7 @@ def perform_operation( ["id_or_name", "browser_id", "page_url", "type"], ["id_or_name", "access_token", "type"], ["id_or_name", "bindings", "browser_id", "input", "page_url", "tool_ref", "type"], + ["id_or_name", "payment_method_id", "type"], ) def perform_operation( self, @@ -1306,7 +1564,9 @@ def perform_operation( | Literal["1pw_fill"] | Literal["1pw_recover"] | Literal["1pw_update_access_token"] - | Literal["webmcp_invoke"], + | Literal["webmcp_invoke"] + | Literal["add_payment_method"] + | Literal["remove_payment_method"], browser_id: str | Omit = omit, page_url: str | Omit = omit, amount: int | Omit = omit, @@ -1332,6 +1592,7 @@ def perform_operation( input: Dict[str, object] | Omit = omit, tool_ref: str | Omit = omit, timeout_sec: int | Omit = omit, + payment_method_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1372,6 +1633,7 @@ def perform_operation( "input": input, "tool_ref": tool_ref, "timeout_sec": timeout_sec, + "payment_method_id": payment_method_id, }, item_perform_operation_params.ItemPerformOperationParams, ), @@ -1407,8 +1669,10 @@ def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: AgentCard wallet. Omit provider_config to use Kernel-managed credentials, or @@ -1459,8 +1723,56 @@ def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. + + Args: + spec: Live Link card request. Test-mode card creation is not supported. The spec can + be changed with PATCH until the card is authorized at a checkout. Authorize it + with the browser at final checkout: Kernel inspects the checkout through WebMCP + and internally chooses a merchant-bound Link Pay Token when supported or a + virtual card otherwise. Callers never receive or choose how the credential is + delivered. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + def upsert( + self, + key: str, + *, + id_or_name: str, + spec: PaymentRequestVaultItemSpecParam, + type: Literal["payment_request"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItem: + """ + Create an item under a key unique within its vault, or retrieve the existing + item when its specification matches. An identical card PUT returns the existing + card in any lifecycle state without polling the provider, reauthorizing, + replacing aliases, or resetting recovery. Conflicting specifications return 409. + Provider-specific authorization requirements and retry behavior are described in + the item's request schema. Do not use credential items to store, collect, or + fill credit card data, including card numbers (PANs), security codes (CVV/CVC), + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: Live Link card request. Test-mode card creation is not supported. The spec can @@ -1503,8 +1815,10 @@ def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: extra_headers: Send extra headers @@ -1540,15 +1854,17 @@ def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: Credential fields are for login and other non-payment credentials. Do not store, - collect, or fill credit card data in credential items. Use wallet and card item - types for credit cards and payment checkout instead. Field order is preserved in - the user-facing collection form, so list fields in the same top-to-bottom order - as the website. + collect, or fill credit card data in credential items. Use wallet, + payment_request and card item types for credit cards and payment checkout + instead. Field order is preserved in the user-facing collection form, so list + fields in the same top-to-bottom order as the website. extra_headers: Send extra headers @@ -1568,9 +1884,14 @@ def upsert( id_or_name: str, spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam + | PaymentRequestVaultItemSpecParam | OnePasswordCredentialAccountSpecParam | CredentialVaultItemSpecInputParam, - type: Literal["wallet"] | Literal["card"] | Literal["credential_account"] | Literal["credential"], + type: Literal["wallet"] + | Literal["card"] + | Literal["payment_request"] + | Literal["credential_account"] + | Literal["credential"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -1737,6 +2058,55 @@ async def update( """ ... + @overload + async def update( + self, + key: str, + *, + id_or_name: str, + spec: PaymentRequestVaultItemSpecParam, + type: Literal["payment_request"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItem: + """ + Credential updates require type credential and the current version, and change + only values or description; omitted values are preserved, nonempty strings + replace, and null or empty strings clear supported fields. Clearing required + text/email/password values returns pending_collection; browser forms still + require nonempty required inputs. Card updates may omit type for compatibility + with legacy requests. Requested cards accept a replacement specification. + Pending issuance requests may update provider-supported fields on their existing + request, subject to atomic provider approval checks; omitted optional fields + remain unchanged and explicit empty lists clear them. Wallet/provider binding + and unsupported fields cannot change after authorization starts. An uncertain + update enters recovery_required; delete the card and create a new one rather + than retrying the update. Checkout cards may be edited between authorizations. A + Link card authorized with browser_id and page_url cannot be changed; delete it + and create a new card with the updated details. + + Args: + spec: Live Link card request. Test-mode card creation is not supported. The spec can + be changed with PATCH until the card is authorized at a checkout. Authorize it + with the browser at final checkout: Kernel inspects the checkout through WebMCP + and internally chooses a merchant-bound Link Pay Token when supported or a + virtual card otherwise. Callers never receive or choose how the credential is + delivered. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @overload async def update( self, @@ -1788,14 +2158,14 @@ async def update( """ ... - @required_args(["id_or_name", "spec"], ["id_or_name", "spec", "type", "version"]) + @required_args(["id_or_name", "spec"], ["id_or_name", "spec", "type"], ["id_or_name", "spec", "type", "version"]) async def update( self, key: str, *, id_or_name: str, - spec: CardVaultItemSpecParam | CredentialVaultItemSpecUpdateParam, - type: Literal["card"] | Literal["credential"] | Omit = omit, + spec: CardVaultItemSpecParam | PaymentRequestVaultItemSpecParam | CredentialVaultItemSpecUpdateParam, + type: Literal["card"] | Literal["payment_request"] | Literal["credential"] | Omit = omit, version: int | Omit = omit, expected_item_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -2005,6 +2375,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. The browser must have this vault attached. @@ -2061,6 +2437,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -2119,6 +2501,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: amount: Actual transaction amount in minor units, no greater than the approved limit. @@ -2176,6 +2564,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -2228,6 +2622,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: checkout: Required when preparing an unused AgentCard card for a supported checkout processor. Consent is bound to this browser and declared merchant origin, not a @@ -2289,6 +2689,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2361,6 +2767,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2418,6 +2830,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2476,6 +2894,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2535,6 +2959,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -2587,6 +3017,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -2642,6 +3078,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2701,6 +3143,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: extra_headers: Send extra headers @@ -2754,6 +3202,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: access_token_expires_at: Optional supplied expiry. Omit to clear the old expiry. @@ -2813,6 +3267,12 @@ async def perform_operation( `failed` or `unknown`. Fill never submits the page, so it is safe to retry after a failure, an `unknown` outcome, or a transport error. + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + Args: browser_id: Browser session ID, not a reusable browser name. @@ -2838,6 +3298,123 @@ async def perform_operation( """ ... + @overload + async def perform_operation( + self, + key: str, + *, + id_or_name: str, + type: Literal["add_payment_method"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize; pass browser_id and page_url from the final checkout + page so Kernel can inspect the checkout. Eligible unused AgentCard cards + advertise prepare_checkout, which requires checkout context and obtains device + approval before native Square Pay. Keep the returned approval page open, poll + until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Ready Kernel cards advertise fill. Fill delivers card details for a few minutes; + submit checkout promptly after filling. A repeated fill is safe. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + async def perform_operation( + self, + key: str, + *, + id_or_name: str, + payment_method_id: str, + type: Literal["remove_payment_method"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItemOperationResponse: + """ + Retrieve the item first and invoke only an operation listed in + `available_operations`, following its natural-language description. Availability + is rechecked at execution time; unavailable operations return 409. Authorization + and preparation may call an external provider and return updated state. Link + cards advertise authorize; pass browser_id and page_url from the final checkout + page so Kernel can inspect the checkout. Eligible unused AgentCard cards + advertise prepare_checkout, which requires checkout context and obtains device + approval before native Square Pay. Keep the returned approval page open, poll + until ready_to_submit, then submit before preparation.expires_at. Unused + preparations expire automatically and cannot be reused. If spend-request + creation is rejected with a non-retryable provider error, the card item is + deleted and the provider's error code and message are returned. Rate limits + return HTTP 429 and retain the card item; stop, back off, and retry the same + authorize operation. + + Ready Kernel cards advertise fill. Fill delivers card details for a few minutes; + submit checkout promptly after filling. A repeated fill is safe. + + Fill returns a value-free execution result. Validation failures before writing + return 400 (invalid request or targets), 403 (access or destination denied), 404 + (resource not found), or 409 (item or browser not ready). Once writing starts, + known partial failures and indeterminate field outcomes return 200 with status + `failed` or `unknown`. Fill never submits the page, so it is safe to retry after + a failure, an `unknown` outcome, or a transport error. + + Connected Kernel wallets may advertise add_payment_method, which returns a + single-use hosted card_enrollment link for a card, and remove_payment_method, + which removes one card without affecting the others. Both operations require + vaults:write in addition to vaults:use on the vault for scoped API keys, and + return 403 without both permissions. + + Args: + payment_method_id: ID from the wallet's payment_methods expansion. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + @required_args( ["id_or_name", "type"], ["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"], @@ -2846,6 +3423,7 @@ async def perform_operation( ["id_or_name", "browser_id", "page_url", "type"], ["id_or_name", "access_token", "type"], ["id_or_name", "bindings", "browser_id", "input", "page_url", "tool_ref", "type"], + ["id_or_name", "payment_method_id", "type"], ) async def perform_operation( self, @@ -2866,7 +3444,9 @@ async def perform_operation( | Literal["1pw_fill"] | Literal["1pw_recover"] | Literal["1pw_update_access_token"] - | Literal["webmcp_invoke"], + | Literal["webmcp_invoke"] + | Literal["add_payment_method"] + | Literal["remove_payment_method"], browser_id: str | Omit = omit, page_url: str | Omit = omit, amount: int | Omit = omit, @@ -2892,6 +3472,7 @@ async def perform_operation( input: Dict[str, object] | Omit = omit, tool_ref: str | Omit = omit, timeout_sec: int | Omit = omit, + payment_method_id: str | Omit = omit, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -2932,6 +3513,7 @@ async def perform_operation( "input": input, "tool_ref": tool_ref, "timeout_sec": timeout_sec, + "payment_method_id": payment_method_id, }, item_perform_operation_params.ItemPerformOperationParams, ), @@ -2967,8 +3549,10 @@ async def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: AgentCard wallet. Omit provider_config to use Kernel-managed credentials, or @@ -3019,8 +3603,56 @@ async def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. + + Args: + spec: Live Link card request. Test-mode card creation is not supported. The spec can + be changed with PATCH until the card is authorized at a checkout. Authorize it + with the browser at final checkout: Kernel inspects the checkout through WebMCP + and internally chooses a merchant-bound Link Pay Token when supported or a + virtual card otherwise. Callers never receive or choose how the credential is + delivered. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + ... + + @overload + async def upsert( + self, + key: str, + *, + id_or_name: str, + spec: PaymentRequestVaultItemSpecParam, + type: Literal["payment_request"], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | httpx.Timeout | None | NotGiven = not_given, + ) -> VaultItem: + """ + Create an item under a key unique within its vault, or retrieve the existing + item when its specification matches. An identical card PUT returns the existing + card in any lifecycle state without polling the provider, reauthorizing, + replacing aliases, or resetting recovery. Conflicting specifications return 409. + Provider-specific authorization requirements and retry behavior are described in + the item's request schema. Do not use credential items to store, collect, or + fill credit card data, including card numbers (PANs), security codes (CVV/CVC), + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: Live Link card request. Test-mode card creation is not supported. The spec can @@ -3063,8 +3695,10 @@ async def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: extra_headers: Send extra headers @@ -3100,15 +3734,17 @@ async def upsert( Provider-specific authorization requirements and retry behavior are described in the item's request schema. Do not use credential items to store, collect, or fill credit card data, including card numbers (PANs), security codes (CVV/CVC), - or expiration dates. Use wallet and card item types for credit cards and payment - checkout instead. + or expiration dates. Use wallet, payment_request and card item types for credit + cards and payment checkout instead. Where enabled, Link and Kernel purchases can + be payment_request items parented by their wallet; card items remain supported + for them and for AgentCard reusable cards. Args: spec: Credential fields are for login and other non-payment credentials. Do not store, - collect, or fill credit card data in credential items. Use wallet and card item - types for credit cards and payment checkout instead. Field order is preserved in - the user-facing collection form, so list fields in the same top-to-bottom order - as the website. + collect, or fill credit card data in credential items. Use wallet, + payment_request and card item types for credit cards and payment checkout + instead. Field order is preserved in the user-facing collection form, so list + fields in the same top-to-bottom order as the website. extra_headers: Send extra headers @@ -3128,9 +3764,14 @@ async def upsert( id_or_name: str, spec: item_upsert_params.WalletVaultItemRequestSpec | CardVaultItemSpecParam + | PaymentRequestVaultItemSpecParam | OnePasswordCredentialAccountSpecParam | CredentialVaultItemSpecInputParam, - type: Literal["wallet"] | Literal["card"] | Literal["credential_account"] | Literal["credential"], + type: Literal["wallet"] + | Literal["card"] + | Literal["payment_request"] + | Literal["credential_account"] + | Literal["credential"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py index 0b6acf2c..439d7d3b 100644 --- a/src/kernel/types/vaults/__init__.py +++ b/src/kernel/types/vaults/__init__.py @@ -27,6 +27,7 @@ from .one_password_oauth_action import OnePasswordOAuthAction as OnePasswordOAuthAction from .card_vault_item_spec_param import CardVaultItemSpecParam as CardVaultItemSpecParam from .credential_vault_item_spec import CredentialVaultItemSpec as CredentialVaultItemSpec +from .payment_request_vault_item import PaymentRequestVaultItem as PaymentRequestVaultItem from .vault_webmcp_binding_param import VaultWebmcpBindingParam as VaultWebmcpBindingParam from .credential_vault_field_type import CredentialVaultFieldType as CredentialVaultFieldType from .credential_vault_item_state import CredentialVaultItemState as CredentialVaultItemState @@ -40,8 +41,10 @@ from .kernel_wallet_vault_item_spec import KernelWalletVaultItemSpec as KernelWalletVaultItemSpec from .vault_item_operation_response import VaultItemOperationResponse as VaultItemOperationResponse from .agentcard_checkout_preparation import AgentcardCheckoutPreparation as AgentcardCheckoutPreparation +from .payment_request_vault_item_spec import PaymentRequestVaultItemSpec as PaymentRequestVaultItemSpec from .agentcard_checkout_authorization import AgentcardCheckoutAuthorization as AgentcardCheckoutAuthorization from .fill_vault_item_operation_result import FillVaultItemOperationResult as FillVaultItemOperationResult +from .payment_request_vault_item_state import PaymentRequestVaultItemState as PaymentRequestVaultItemState from .credential_vault_field_definition import CredentialVaultFieldDefinition as CredentialVaultFieldDefinition from .kernel_card_vault_item_spec_param import KernelCardVaultItemSpecParam as KernelCardVaultItemSpecParam from .kernel_credential_vault_item_spec import KernelCredentialVaultItemSpec as KernelCredentialVaultItemSpec @@ -56,9 +59,13 @@ from .one_password_credential_account_state import ( OnePasswordCredentialAccountState as OnePasswordCredentialAccountState, ) +from .payment_request_vault_item_spec_param import PaymentRequestVaultItemSpecParam as PaymentRequestVaultItemSpecParam from .credential_vault_item_spec_input_param import ( CredentialVaultItemSpecInputParam as CredentialVaultItemSpecInputParam, ) +from .kernel_payment_request_vault_item_spec import ( + KernelPaymentRequestVaultItemSpec as KernelPaymentRequestVaultItemSpec, +) from .credential_vault_item_spec_update_param import ( CredentialVaultItemSpecUpdateParam as CredentialVaultItemSpecUpdateParam, ) @@ -95,6 +102,9 @@ from .authorize_vault_item_operation_request_param import ( AuthorizeVaultItemOperationRequestParam as AuthorizeVaultItemOperationRequestParam, ) +from .kernel_payment_request_vault_item_spec_param import ( + KernelPaymentRequestVaultItemSpecParam as KernelPaymentRequestVaultItemSpecParam, +) from .credential_vault_field_definition_input_param import ( CredentialVaultFieldDefinitionInputParam as CredentialVaultFieldDefinitionInputParam, ) @@ -104,6 +114,9 @@ from .one_password_fill_vault_item_operation_result import ( OnePasswordFillVaultItemOperationResult as OnePasswordFillVaultItemOperationResult, ) +from .add_payment_method_vault_item_operation_result import ( + AddPaymentMethodVaultItemOperationResult as AddPaymentMethodVaultItemOperationResult, +) from .arm_passkey_vault_item_operation_request_param import ( ArmPasskeyVaultItemOperationRequestParam as ArmPasskeyVaultItemOperationRequestParam, ) @@ -113,6 +126,9 @@ from .disarm_passkey_vault_item_operation_request_param import ( DisarmPasskeyVaultItemOperationRequestParam as DisarmPasskeyVaultItemOperationRequestParam, ) +from .remove_payment_method_vault_item_operation_result import ( + RemovePaymentMethodVaultItemOperationResult as RemovePaymentMethodVaultItemOperationResult, +) from .managed_auth_credential_vault_item_spec_input_param import ( ManagedAuthCredentialVaultItemSpecInputParam as ManagedAuthCredentialVaultItemSpecInputParam, ) @@ -128,6 +144,9 @@ from .one_password_fill_vault_item_operation_request_param import ( OnePasswordFillVaultItemOperationRequestParam as OnePasswordFillVaultItemOperationRequestParam, ) +from .add_payment_method_vault_item_operation_request_param import ( + AddPaymentMethodVaultItemOperationRequestParam as AddPaymentMethodVaultItemOperationRequestParam, +) from .confirm_transaction_vault_item_operation_request_param import ( ConfirmTransactionVaultItemOperationRequestParam as ConfirmTransactionVaultItemOperationRequestParam, ) @@ -137,6 +156,9 @@ from .restart_verification_vault_item_operation_request_param import ( RestartVerificationVaultItemOperationRequestParam as RestartVerificationVaultItemOperationRequestParam, ) +from .remove_payment_method_vault_item_operation_request_param import ( + RemovePaymentMethodVaultItemOperationRequestParam as RemovePaymentMethodVaultItemOperationRequestParam, +) from .one_password_request_access_vault_item_operation_request_param import ( OnePasswordRequestAccessVaultItemOperationRequestParam as OnePasswordRequestAccessVaultItemOperationRequestParam, ) diff --git a/src/kernel/types/vaults/add_payment_method_vault_item_operation_request_param.py b/src/kernel/types/vaults/add_payment_method_vault_item_operation_request_param.py new file mode 100644 index 00000000..ad7bde5d --- /dev/null +++ b/src/kernel/types/vaults/add_payment_method_vault_item_operation_request_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["AddPaymentMethodVaultItemOperationRequestParam"] + + +class AddPaymentMethodVaultItemOperationRequestParam(TypedDict, total=False): + """ + Start hosted enrollment of a card in a connected Kernel wallet, including its first card, only when the wallet advertises add_payment_method. Returns a new payment method in pending_enrollment with a single-use card_enrollment URL for the cardholder. Card details go directly to the card vault and are never accepted by this API. Each call creates a separate link that expires after 30 minutes; a failed or expired enrollment does not affect the wallet's other payment methods. Scoped API keys require vaults:write in addition to vaults:use on this vault; otherwise the operation returns 403. + """ + + type: Required[Literal["add_payment_method"]] diff --git a/src/kernel/types/vaults/add_payment_method_vault_item_operation_result.py b/src/kernel/types/vaults/add_payment_method_vault_item_operation_result.py new file mode 100644 index 00000000..a858ed3d --- /dev/null +++ b/src/kernel/types/vaults/add_payment_method_vault_item_operation_result.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ..._models import BaseModel +from .vault_payment_method import VaultPaymentMethod + +__all__ = ["AddPaymentMethodVaultItemOperationResult"] + + +class AddPaymentMethodVaultItemOperationResult(BaseModel): + """The payment method created in pending_enrollment. + + Deliver action.url to the cardholder; it is a single-use capability and must not be logged. Observe completion through the wallet's payment_methods expansion. + """ + + payment_method: VaultPaymentMethod + + type: Literal["add_payment_method"] diff --git a/src/kernel/types/vaults/credential_account_vault_item.py b/src/kernel/types/vaults/credential_account_vault_item.py index b2f818f6..f33ee788 100644 --- a/src/kernel/types/vaults/credential_account_vault_item.py +++ b/src/kernel/types/vaults/credential_account_vault_item.py @@ -46,6 +46,8 @@ class AvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] diff --git a/src/kernel/types/vaults/credential_vault_item.py b/src/kernel/types/vaults/credential_vault_item.py index b7da27d3..6b6a1f69 100644 --- a/src/kernel/types/vaults/credential_vault_item.py +++ b/src/kernel/types/vaults/credential_vault_item.py @@ -53,6 +53,8 @@ class AvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] diff --git a/src/kernel/types/vaults/credential_vault_item_request_param.py b/src/kernel/types/vaults/credential_vault_item_request_param.py index 4034d9c5..61337f3b 100644 --- a/src/kernel/types/vaults/credential_vault_item_request_param.py +++ b/src/kernel/types/vaults/credential_vault_item_request_param.py @@ -17,7 +17,7 @@ class CredentialVaultItemRequestParam(TypedDict, total=False): or that path fails, collect a Kernel-hosted credential item instead. Never automatically retry an uncertain 1Password request. After an uncertain fill, inspect the page to see the result of the fill. - Do not use credential items for credit card data. Use wallet and card item types instead. + Do not use credential items for credit card data. Use wallet, payment_request and card item types instead. Kernel credentials declare fields and may enter pending_collection. 1Password credentials either reference a connected credential_account or store a supplied access token and integration key encrypted on the item. @@ -32,10 +32,10 @@ class CredentialVaultItemRequestParam(TypedDict, total=False): spec: Required[CredentialVaultItemSpecInputParam] """Credential fields are for login and other non-payment credentials. - Do not store, collect, or fill credit card data in credential items. Use wallet - and card item types for credit cards and payment checkout instead. Field order - is preserved in the user-facing collection form, so list fields in the same - top-to-bottom order as the website. + Do not store, collect, or fill credit card data in credential items. Use wallet, + payment_request and card item types for credit cards and payment checkout + instead. Field order is preserved in the user-facing collection form, so list + fields in the same top-to-bottom order as the website. """ type: Required[Literal["credential"]] diff --git a/src/kernel/types/vaults/item_perform_operation_params.py b/src/kernel/types/vaults/item_perform_operation_params.py index 83729ceb..60fe34c5 100644 --- a/src/kernel/types/vaults/item_perform_operation_params.py +++ b/src/kernel/types/vaults/item_perform_operation_params.py @@ -29,6 +29,8 @@ "OnePasswordRecoverVaultItemOperationRequest", "OnePasswordUpdateAccessTokenVaultItemOperationRequest", "WebmcpInvokeVaultItemOperationRequest", + "AddPaymentMethodVaultItemOperationRequest", + "RemovePaymentMethodVaultItemOperationRequest", ] @@ -269,6 +271,21 @@ class WebmcpInvokeVaultItemOperationRequest(TypedDict, total=False): """ +class AddPaymentMethodVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + type: Required[Literal["add_payment_method"]] + + +class RemovePaymentMethodVaultItemOperationRequest(TypedDict, total=False): + id_or_name: Required[str] + + payment_method_id: Required[str] + """ID from the wallet's payment_methods expansion.""" + + type: Required[Literal["remove_payment_method"]] + + ItemPerformOperationParams: TypeAlias = Union[ AuthorizeVaultItemOperationRequest, RestartVerificationVaultItemOperationRequest, @@ -285,4 +302,6 @@ class WebmcpInvokeVaultItemOperationRequest(TypedDict, total=False): OnePasswordRecoverVaultItemOperationRequest, OnePasswordUpdateAccessTokenVaultItemOperationRequest, WebmcpInvokeVaultItemOperationRequest, + AddPaymentMethodVaultItemOperationRequest, + RemovePaymentMethodVaultItemOperationRequest, ] diff --git a/src/kernel/types/vaults/item_update_params.py b/src/kernel/types/vaults/item_update_params.py index 33e3ad08..6a8b4e7a 100644 --- a/src/kernel/types/vaults/item_update_params.py +++ b/src/kernel/types/vaults/item_update_params.py @@ -6,9 +6,15 @@ from typing_extensions import Literal, Required, TypeAlias, TypedDict from .card_vault_item_spec_param import CardVaultItemSpecParam +from .payment_request_vault_item_spec_param import PaymentRequestVaultItemSpecParam from .credential_vault_item_spec_update_param import CredentialVaultItemSpecUpdateParam -__all__ = ["ItemUpdateParams", "CardVaultItemUpdateRequest", "CredentialVaultItemUpdateRequest"] +__all__ = [ + "ItemUpdateParams", + "CardVaultItemUpdateRequest", + "PaymentRequestVaultItemUpdateRequest", + "CredentialVaultItemUpdateRequest", +] class CardVaultItemUpdateRequest(TypedDict, total=False): @@ -27,6 +33,22 @@ class CardVaultItemUpdateRequest(TypedDict, total=False): type: Literal["card"] +class PaymentRequestVaultItemUpdateRequest(TypedDict, total=False): + id_or_name: Required[str] + + spec: Required[PaymentRequestVaultItemSpecParam] + """Live Link card request. + + Test-mode card creation is not supported. The spec can be changed with PATCH + until the card is authorized at a checkout. Authorize it with the browser at + final checkout: Kernel inspects the checkout through WebMCP and internally + chooses a merchant-bound Link Pay Token when supported or a virtual card + otherwise. Callers never receive or choose how the credential is delivered. + """ + + type: Required[Literal["payment_request"]] + + class CredentialVaultItemUpdateRequest(TypedDict, total=False): id_or_name: Required[str] @@ -46,4 +68,6 @@ class CredentialVaultItemUpdateRequest(TypedDict, total=False): """ -ItemUpdateParams: TypeAlias = Union[CardVaultItemUpdateRequest, CredentialVaultItemUpdateRequest] +ItemUpdateParams: TypeAlias = Union[ + CardVaultItemUpdateRequest, PaymentRequestVaultItemUpdateRequest, CredentialVaultItemUpdateRequest +] diff --git a/src/kernel/types/vaults/item_upsert_params.py b/src/kernel/types/vaults/item_upsert_params.py index 04bd3f11..1930e04e 100644 --- a/src/kernel/types/vaults/item_upsert_params.py +++ b/src/kernel/types/vaults/item_upsert_params.py @@ -7,6 +7,7 @@ from .card_vault_item_spec_param import CardVaultItemSpecParam from .kernel_wallet_vault_item_spec_param import KernelWalletVaultItemSpecParam +from .payment_request_vault_item_spec_param import PaymentRequestVaultItemSpecParam from .credential_vault_item_spec_input_param import CredentialVaultItemSpecInputParam from .one_password_credential_account_spec_param import OnePasswordCredentialAccountSpecParam @@ -25,6 +26,7 @@ "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpec", "WalletVaultItemRequestSpecAgentCardWalletVaultItemSpecProviderConfig", "CardVaultItemRequest", + "PaymentRequestVaultItemRequest", "CredentialAccountVaultItemRequest", "CredentialVaultItemRequest", ] @@ -207,6 +209,22 @@ class CardVaultItemRequest(TypedDict, total=False): type: Required[Literal["card"]] +class PaymentRequestVaultItemRequest(TypedDict, total=False): + id_or_name: Required[str] + + spec: Required[PaymentRequestVaultItemSpecParam] + """Live Link card request. + + Test-mode card creation is not supported. The spec can be changed with PATCH + until the card is authorized at a checkout. Authorize it with the browser at + final checkout: Kernel inspects the checkout through WebMCP and internally + chooses a merchant-bound Link Pay Token when supported or a virtual card + otherwise. Callers never receive or choose how the credential is delivered. + """ + + type: Required[Literal["payment_request"]] + + class CredentialAccountVaultItemRequest(TypedDict, total=False): id_or_name: Required[str] @@ -221,15 +239,19 @@ class CredentialVaultItemRequest(TypedDict, total=False): spec: Required[CredentialVaultItemSpecInputParam] """Credential fields are for login and other non-payment credentials. - Do not store, collect, or fill credit card data in credential items. Use wallet - and card item types for credit cards and payment checkout instead. Field order - is preserved in the user-facing collection form, so list fields in the same - top-to-bottom order as the website. + Do not store, collect, or fill credit card data in credential items. Use wallet, + payment_request and card item types for credit cards and payment checkout + instead. Field order is preserved in the user-facing collection form, so list + fields in the same top-to-bottom order as the website. """ type: Required[Literal["credential"]] ItemUpsertParams: TypeAlias = Union[ - WalletVaultItemRequest, CardVaultItemRequest, CredentialAccountVaultItemRequest, CredentialVaultItemRequest + WalletVaultItemRequest, + CardVaultItemRequest, + PaymentRequestVaultItemRequest, + CredentialAccountVaultItemRequest, + CredentialVaultItemRequest, ] diff --git a/src/kernel/types/vaults/kernel_card_state.py b/src/kernel/types/vaults/kernel_card_state.py index e4732f2a..0838182c 100644 --- a/src/kernel/types/vaults/kernel_card_state.py +++ b/src/kernel/types/vaults/kernel_card_state.py @@ -68,6 +68,23 @@ class KernelCardState(BaseModel): Fill is locked to merchant_url's exact origin. """ + funding_status: Optional[Literal["available", "unavailable", "removed"]] = None + """Whether payment_method_id can still fund this purchase. + + unavailable means the method is being removed or awaits recovery, so + authorization, fill and confirmation are refused until it recovers. removed + means the method was removed from its wallet, so this purchase can no longer be + paid; create a new purchase with another method. Neither changes status, which + still reports what already happened to this purchase. + """ + masks: Optional[Masks] = None + payment_method_id: Optional[str] = None + """Wallet-scoped ID of the payment method funding this purchase. + + It is bound when the purchase is created and never changes; purchases created + before payment methods could be selected report the wallet's default card, card. + """ + status_reason: Optional[str] = None diff --git a/src/kernel/types/vaults/kernel_card_vault_item_spec.py b/src/kernel/types/vaults/kernel_card_vault_item_spec.py index d6c2c93c..525321d6 100644 --- a/src/kernel/types/vaults/kernel_card_vault_item_spec.py +++ b/src/kernel/types/vaults/kernel_card_vault_item_spec.py @@ -52,3 +52,12 @@ class KernelCardVaultItemSpec(BaseModel): Required for Visa cards, whose one-time code is issued for the merchant's country. """ + + payment_method_id: Optional[str] = None + """Wallet-scoped payment method ID from the wallet's payment_methods expansion. + + Omission selects the wallet's default card, ID card, for compatibility with + existing requests; it never falls back to another method, and a wallet without a + default card requires the ID. The purchase is bound to the method's enrolled + card and network token, so later operations cannot switch funding. + """ diff --git a/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py b/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py index e836f734..a540a547 100644 --- a/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py +++ b/src/kernel/types/vaults/kernel_card_vault_item_spec_param.py @@ -51,3 +51,12 @@ class KernelCardVaultItemSpecParam(TypedDict, total=False): Required for Visa cards, whose one-time code is issued for the merchant's country. """ + + payment_method_id: str + """Wallet-scoped payment method ID from the wallet's payment_methods expansion. + + Omission selects the wallet's default card, ID card, for compatibility with + existing requests; it never falls back to another method, and a wallet without a + default card requires the ID. The purchase is bound to the method's enrolled + card and network token, so later operations cannot switch funding. + """ diff --git a/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py b/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py index d8ae9257..653eec3c 100644 --- a/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py +++ b/src/kernel/types/vaults/kernel_credential_vault_item_spec_input_param.py @@ -13,7 +13,7 @@ class KernelCredentialVaultItemSpecInputParam(TypedDict, total=False): """Credential fields are for login and other non-payment credentials. - Do not store, collect, or fill credit card data in credential items. Use wallet and card item types for credit cards and payment checkout instead. Field order is preserved in the user-facing collection form, so list fields in the same top-to-bottom order as the website. + Do not store, collect, or fill credit card data in credential items. Use wallet, payment_request and card item types for credit cards and payment checkout instead. Field order is preserved in the user-facing collection form, so list fields in the same top-to-bottom order as the website. """ fields: Required[Iterable[CredentialVaultFieldInputParam]] diff --git a/src/kernel/types/vaults/kernel_payment_request_vault_item_spec.py b/src/kernel/types/vaults/kernel_payment_request_vault_item_spec.py new file mode 100644 index 00000000..c9657a0a --- /dev/null +++ b/src/kernel/types/vaults/kernel_payment_request_vault_item_spec.py @@ -0,0 +1,56 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["KernelPaymentRequestVaultItemSpec"] + + +class KernelPaymentRequestVaultItemSpec(BaseModel): + """ + One live purchase funded by the Kernel wallet payment method named by payment_method_id. The method must be active and eligible when the request is created. The purchase is bound to that method; later operations cannot switch funding, and removing the method makes the purchase unusable rather than moving it to another card. Approval, issuance, fill and the alias fallback behave as described for KernelCardVaultItemSpec. + """ + + amount: int + """ + Integer amount in minor currency units (at most 1000000), bound to the one-time + code. + """ + + currency: str + """ISO 4217 code. + + Supported: aud, brl, cad, chf, czk, dkk, eur, gbp, hkd, inr, jpy, krw, mxn, nok, + nzd, pln, sek, sgd, usd, zar. + """ + + merchant_name: str + + merchant_url: str + """Merchant checkout URL. Fill is allowed only on this URL's origin.""" + + payment_method_id: str + """Payment method ID from the wallet's payment_methods expansion.""" + + provider: Literal["kernel"] + + wallet: str + """Key of the Kernel wallet item that owns the payment method.""" + + merchant_category: Optional[str] = None + """Actual merchant category when known. Omit rather than invent a category.""" + + merchant_category_code: Optional[str] = None + """Actual merchant MCC when known. + + Omit rather than invent a code. 0000 is not accepted. + """ + + merchant_country: Optional[str] = None + """The merchant's ISO 3166-1 alpha-2 country code. + + Required for Visa cards, whose one-time code is issued for the merchant's + country. + """ diff --git a/src/kernel/types/vaults/kernel_payment_request_vault_item_spec_param.py b/src/kernel/types/vaults/kernel_payment_request_vault_item_spec_param.py new file mode 100644 index 00000000..87cbaeb0 --- /dev/null +++ b/src/kernel/types/vaults/kernel_payment_request_vault_item_spec_param.py @@ -0,0 +1,55 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["KernelPaymentRequestVaultItemSpecParam"] + + +class KernelPaymentRequestVaultItemSpecParam(TypedDict, total=False): + """ + One live purchase funded by the Kernel wallet payment method named by payment_method_id. The method must be active and eligible when the request is created. The purchase is bound to that method; later operations cannot switch funding, and removing the method makes the purchase unusable rather than moving it to another card. Approval, issuance, fill and the alias fallback behave as described for KernelCardVaultItemSpec. + """ + + amount: Required[int] + """ + Integer amount in minor currency units (at most 1000000), bound to the one-time + code. + """ + + currency: Required[str] + """ISO 4217 code. + + Supported: aud, brl, cad, chf, czk, dkk, eur, gbp, hkd, inr, jpy, krw, mxn, nok, + nzd, pln, sek, sgd, usd, zar. + """ + + merchant_name: Required[str] + + merchant_url: Required[str] + """Merchant checkout URL. Fill is allowed only on this URL's origin.""" + + payment_method_id: Required[str] + """Payment method ID from the wallet's payment_methods expansion.""" + + provider: Required[Literal["kernel"]] + + wallet: Required[str] + """Key of the Kernel wallet item that owns the payment method.""" + + merchant_category: str + """Actual merchant category when known. Omit rather than invent a category.""" + + merchant_category_code: str + """Actual merchant MCC when known. + + Omit rather than invent a code. 0000 is not accepted. + """ + + merchant_country: str + """The merchant's ISO 3166-1 alpha-2 country code. + + Required for Visa cards, whose one-time code is issued for the merchant's + country. + """ diff --git a/src/kernel/types/vaults/kernel_wallet_state.py b/src/kernel/types/vaults/kernel_wallet_state.py index a35239d7..0953b867 100644 --- a/src/kernel/types/vaults/kernel_wallet_state.py +++ b/src/kernel/types/vaults/kernel_wallet_state.py @@ -12,13 +12,20 @@ class KernelWalletState(BaseModel): provider: Literal["kernel"] status: Literal["pending_authorization", "connected", "reconnect_required", "degraded"] - """pending_authorization asks the cardholder to use the card_enrollment action. - - connected means the card is stored; it can pay once payment_methods reports - capabilities.single_use_card.eligible. reconnect_required asks the cardholder to - use a new card_enrollment action after an uncertain enrollment was safely - removed. degraded means the enrollment outcome is unknown and the wallet must be - deleted before adding another card. + """connected means the wallet is usable. + + It holds zero or more cards as payment methods, listed by the payment_methods + expansion, and each can pay once it reports + capabilities.single_use_card.eligible. A wallet with no cards, before its first + card or after its last is removed, is still connected. Where the wallet + advertises add_payment_method and remove_payment_method, use them to manage + cards. Otherwise the wallet enrolls one default card when created; until that + card is enrolled the wallet reports pending_authorization with the card's + card_enrollment action, or degraded when the card's enrollment outcome is + unknown and the wallet must be deleted before adding another card. + reconnect_required appears only on a wallet created before cards were payment + methods and not yet upgraded. Reads preserve its stored state until the operator + upgrade; payment and deletion requests are refused until then. """ status_reason: Optional[str] = None diff --git a/src/kernel/types/vaults/kernel_wallet_vault_item_spec.py b/src/kernel/types/vaults/kernel_wallet_vault_item_spec.py index fb2f039e..3cbd225c 100644 --- a/src/kernel/types/vaults/kernel_wallet_vault_item_spec.py +++ b/src/kernel/types/vaults/kernel_wallet_vault_item_spec.py @@ -8,9 +8,8 @@ class KernelWalletVaultItemSpec(BaseModel): - """One card stored with Kernel-managed credentials. - - Creation returns a card_enrollment action: the cardholder enters the card and their email on a Kernel-hosted page, and the wallet connects once the card is stored. Kernel then enrolls it for an agentic network token when the issuer supports it. The card number never reaches Kernel. The connected wallet's payment_methods expansion lists the card; capabilities.single_use_card.eligible is false, with a network_token_* reason, until the card has a network token, and authorize returns 400 for such a card unless Kernel supports checkout delivery without a network token for that card. In that case, fill types the checkout details. Visa purchases require the cardholder to complete a spend_approval action before Kernel issues a one-time code; Mastercard purchases need no hosted approval. + """ + Cards stored with Kernel-managed credentials, each a payment method of the wallet. Each card is enrolled through a card_enrollment action: the cardholder enters the card and their email on a Kernel-hosted page. Where the wallet advertises add_payment_method, creation returns an empty connected wallet and each card is enrolled with that operation. Otherwise creation returns the wallet's default card's card_enrollment action, and the wallet connects once that card is stored. Kernel then enrolls each card for an agentic network token when the issuer supports it. The card number never reaches Kernel. The connected wallet's payment_methods expansion lists the cards; capabilities.single_use_card.eligible is false, with a network_token_* reason, until the card has a network token, and authorize returns 400 for such a card unless Kernel supports checkout delivery without a network token for that card. In that case, fill types the checkout details. Visa purchases require the cardholder to complete a spend_approval action before Kernel issues a one-time code; Mastercard purchases need no hosted approval. """ provider: Literal["kernel"] diff --git a/src/kernel/types/vaults/kernel_wallet_vault_item_spec_param.py b/src/kernel/types/vaults/kernel_wallet_vault_item_spec_param.py index b0e87117..e560f119 100644 --- a/src/kernel/types/vaults/kernel_wallet_vault_item_spec_param.py +++ b/src/kernel/types/vaults/kernel_wallet_vault_item_spec_param.py @@ -8,9 +8,8 @@ class KernelWalletVaultItemSpecParam(TypedDict, total=False): - """One card stored with Kernel-managed credentials. - - Creation returns a card_enrollment action: the cardholder enters the card and their email on a Kernel-hosted page, and the wallet connects once the card is stored. Kernel then enrolls it for an agentic network token when the issuer supports it. The card number never reaches Kernel. The connected wallet's payment_methods expansion lists the card; capabilities.single_use_card.eligible is false, with a network_token_* reason, until the card has a network token, and authorize returns 400 for such a card unless Kernel supports checkout delivery without a network token for that card. In that case, fill types the checkout details. Visa purchases require the cardholder to complete a spend_approval action before Kernel issues a one-time code; Mastercard purchases need no hosted approval. + """ + Cards stored with Kernel-managed credentials, each a payment method of the wallet. Each card is enrolled through a card_enrollment action: the cardholder enters the card and their email on a Kernel-hosted page. Where the wallet advertises add_payment_method, creation returns an empty connected wallet and each card is enrolled with that operation. Otherwise creation returns the wallet's default card's card_enrollment action, and the wallet connects once that card is stored. Kernel then enrolls each card for an agentic network token when the issuer supports it. The card number never reaches Kernel. The connected wallet's payment_methods expansion lists the cards; capabilities.single_use_card.eligible is false, with a network_token_* reason, until the card has a network token, and authorize returns 400 for such a card unless Kernel supports checkout delivery without a network token for that card. In that case, fill types the checkout details. Visa purchases require the cardholder to complete a spend_approval action before Kernel issues a one-time code; Mastercard purchases need no hosted approval. """ provider: Required[Literal["kernel"]] diff --git a/src/kernel/types/vaults/payment_request_vault_item.py b/src/kernel/types/vaults/payment_request_vault_item.py new file mode 100644 index 00000000..48ef3809 --- /dev/null +++ b/src/kernel/types/vaults/payment_request_vault_item.py @@ -0,0 +1,93 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal + +from ..._models import BaseModel +from .vault_item_action import VaultItemAction +from .payment_request_vault_item_spec import PaymentRequestVaultItemSpec +from .payment_request_vault_item_state import PaymentRequestVaultItemState + +__all__ = ["PaymentRequestVaultItem", "AvailableExpansion", "AvailableOperation"] + + +class AvailableExpansion(BaseModel): + """ + Live data that can currently be requested by passing its type to the item GET expand parameter. + """ + + description: str + + type: Literal["payment_methods", "link_user_info", "link_shipping_addresses"] + + +class AvailableOperation(BaseModel): + """An operation that is currently valid for this item. + + Read the description before invoking it through the item operations endpoint. + """ + + description: str + + type: Literal[ + "authorize", + "restart_verification", + "confirm_transaction", + "collect", + "prepare_checkout", + "fill", + "arm_passkey", + "register_passkey", + "disarm_passkey", + "1pw_create_access_request", + "1pw_access_request_status", + "1pw_fill", + "1pw_recover", + "1pw_update_access_token", + "webmcp_invoke", + "add_payment_method", + "remove_payment_method", + ] + + +class PaymentRequestVaultItem(BaseModel): + """One purchase from a Link or Kernel wallet, parented by that wallet. + + It has the same lifecycle, operations and fill behavior as a Link or Kernel card item. AgentCard reusable cards remain card items. + """ + + id: str + + available_expansions: List[AvailableExpansion] + + available_operations: List[AvailableOperation] + + created_at: datetime + + key: str + """Immutable item key assigned when the item is created.""" + + spec: PaymentRequestVaultItemSpec + """Live Link card request. + + Test-mode card creation is not supported. The spec can be changed with PATCH + until the card is authorized at a checkout. Authorize it with the browser at + final checkout: Kernel inspects the checkout through WebMCP and internally + chooses a merchant-bound Link Pay Token when supported or a virtual card + otherwise. Callers never receive or choose how the credential is delivered. + """ + + state: PaymentRequestVaultItemState + """Issued Link cards retain encrypted card material for the fill operation. + + Link cards do not expose aliases or support egress substitution. + """ + + type: Literal["payment_request"] + + updated_at: datetime + + action: Optional[VaultItemAction] = None + + expires_at: Optional[datetime] = None diff --git a/src/kernel/types/vaults/payment_request_vault_item_spec.py b/src/kernel/types/vaults/payment_request_vault_item_spec.py new file mode 100644 index 00000000..a06517ad --- /dev/null +++ b/src/kernel/types/vaults/payment_request_vault_item_spec.py @@ -0,0 +1,125 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, Annotated, TypeAlias + +from ..._utils import PropertyInfo +from ..._models import BaseModel +from .kernel_payment_request_vault_item_spec import KernelPaymentRequestVaultItemSpec + +__all__ = [ + "PaymentRequestVaultItemSpec", + "LinkCardVaultItemSpec", + "LinkCardVaultItemSpecLineItem", + "LinkCardVaultItemSpecLineItemTotal", + "LinkCardVaultItemSpecRecurring", + "LinkCardVaultItemSpecTotal", +] + + +class LinkCardVaultItemSpecLineItemTotal(BaseModel): + amount: int + """Total amount in minor currency units.""" + + display_text: str + + type: str + + +class LinkCardVaultItemSpecLineItem(BaseModel): + name: str + + description: Optional[str] = None + + image_url: Optional[str] = None + + product_url: Optional[str] = None + + quantity: Optional[int] = None + + sku: Optional[str] = None + + totals: Optional[List[LinkCardVaultItemSpecLineItemTotal]] = None + + unit_amount: Optional[int] = None + """Unit amount in minor currency units.""" + + url: Optional[str] = None + + +class LinkCardVaultItemSpecRecurring(BaseModel): + """Recurring terms for a subscription or other repeated purchase. + + The amount becomes the spending limit for each period of interval_count intervals, for example every 2 weeks. The merchant schedules charges. The card stays ready after each charge until it expires or is deleted; do not create a new card each period. Deleting the card, its wallet or its vault first cancels the credential with Link, so later charges decline; if Link cannot be reached, deletion returns 409 provider_revocation_pending and should be retried. Deletion does not cancel the subscription with the merchant. Recurring terms cannot be changed once the card is authorized. + """ + + interval: Literal["day", "week", "month", "year"] + + interval_count: Optional[int] = None + """Number of intervals per period. Link defaults it to 1.""" + + +class LinkCardVaultItemSpecTotal(BaseModel): + amount: int + """Total amount in minor currency units.""" + + display_text: str + + type: str + + +class LinkCardVaultItemSpec(BaseModel): + """Live Link card request. + + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + """ + + amount: int + """Integer amount in minor currency units, at most 50000. + + With recurring, the spending limit per period, not a lifetime total. + """ + + context: str + + currency: str + + merchant_name: str + + merchant_url: str + + payment_method_id: str + """Payment-method ID returned by the referenced wallet's payment-method listing. + + The provider decides whether the selected funding method can satisfy the card + request. + """ + + provider: Literal["link"] + + wallet: str + """Connected Link wallet item key.""" + + line_items: Optional[List[LinkCardVaultItemSpecLineItem]] = None + + metadata: Optional[Dict[str, str]] = None + + recurring: Optional[LinkCardVaultItemSpecRecurring] = None + """Recurring terms for a subscription or other repeated purchase. + + The amount becomes the spending limit for each period of interval_count + intervals, for example every 2 weeks. The merchant schedules charges. The card + stays ready after each charge until it expires or is deleted; do not create a + new card each period. Deleting the card, its wallet or its vault first cancels + the credential with Link, so later charges decline; if Link cannot be reached, + deletion returns 409 provider_revocation_pending and should be retried. Deletion + does not cancel the subscription with the merchant. Recurring terms cannot be + changed once the card is authorized. + """ + + totals: Optional[List[LinkCardVaultItemSpecTotal]] = None + + +PaymentRequestVaultItemSpec: TypeAlias = Annotated[ + Union[LinkCardVaultItemSpec, KernelPaymentRequestVaultItemSpec], PropertyInfo(discriminator="provider") +] diff --git a/src/kernel/types/vaults/payment_request_vault_item_spec_param.py b/src/kernel/types/vaults/payment_request_vault_item_spec_param.py new file mode 100644 index 00000000..9fa58699 --- /dev/null +++ b/src/kernel/types/vaults/payment_request_vault_item_spec_param.py @@ -0,0 +1,123 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing import Dict, Union, Iterable +from typing_extensions import Literal, Required, TypeAlias, TypedDict + +from .kernel_payment_request_vault_item_spec_param import KernelPaymentRequestVaultItemSpecParam + +__all__ = [ + "PaymentRequestVaultItemSpecParam", + "LinkCardVaultItemSpec", + "LinkCardVaultItemSpecLineItem", + "LinkCardVaultItemSpecLineItemTotal", + "LinkCardVaultItemSpecRecurring", + "LinkCardVaultItemSpecTotal", +] + + +class LinkCardVaultItemSpecLineItemTotal(TypedDict, total=False): + amount: Required[int] + """Total amount in minor currency units.""" + + display_text: Required[str] + + type: Required[str] + + +class LinkCardVaultItemSpecLineItem(TypedDict, total=False): + name: Required[str] + + description: str + + image_url: str + + product_url: str + + quantity: int + + sku: str + + totals: Iterable[LinkCardVaultItemSpecLineItemTotal] + + unit_amount: int + """Unit amount in minor currency units.""" + + url: str + + +class LinkCardVaultItemSpecRecurring(TypedDict, total=False): + """Recurring terms for a subscription or other repeated purchase. + + The amount becomes the spending limit for each period of interval_count intervals, for example every 2 weeks. The merchant schedules charges. The card stays ready after each charge until it expires or is deleted; do not create a new card each period. Deleting the card, its wallet or its vault first cancels the credential with Link, so later charges decline; if Link cannot be reached, deletion returns 409 provider_revocation_pending and should be retried. Deletion does not cancel the subscription with the merchant. Recurring terms cannot be changed once the card is authorized. + """ + + interval: Required[Literal["day", "week", "month", "year"]] + + interval_count: int + """Number of intervals per period. Link defaults it to 1.""" + + +class LinkCardVaultItemSpecTotal(TypedDict, total=False): + amount: Required[int] + """Total amount in minor currency units.""" + + display_text: Required[str] + + type: Required[str] + + +class LinkCardVaultItemSpec(TypedDict, total=False): + """Live Link card request. + + Test-mode card creation is not supported. The spec can be changed with PATCH until the card is authorized at a checkout. Authorize it with the browser at final checkout: Kernel inspects the checkout through WebMCP and internally chooses a merchant-bound Link Pay Token when supported or a virtual card otherwise. Callers never receive or choose how the credential is delivered. + """ + + amount: Required[int] + """Integer amount in minor currency units, at most 50000. + + With recurring, the spending limit per period, not a lifetime total. + """ + + context: Required[str] + + currency: Required[str] + + merchant_name: Required[str] + + merchant_url: Required[str] + + payment_method_id: Required[str] + """Payment-method ID returned by the referenced wallet's payment-method listing. + + The provider decides whether the selected funding method can satisfy the card + request. + """ + + provider: Required[Literal["link"]] + + wallet: Required[str] + """Connected Link wallet item key.""" + + line_items: Iterable[LinkCardVaultItemSpecLineItem] + + metadata: Dict[str, str] + + recurring: LinkCardVaultItemSpecRecurring + """Recurring terms for a subscription or other repeated purchase. + + The amount becomes the spending limit for each period of interval_count + intervals, for example every 2 weeks. The merchant schedules charges. The card + stays ready after each charge until it expires or is deleted; do not create a + new card each period. Deleting the card, its wallet or its vault first cancels + the credential with Link, so later charges decline; if Link cannot be reached, + deletion returns 409 provider_revocation_pending and should be retried. Deletion + does not cancel the subscription with the merchant. Recurring terms cannot be + changed once the card is authorized. + """ + + totals: Iterable[LinkCardVaultItemSpecTotal] + + +PaymentRequestVaultItemSpecParam: TypeAlias = Union[LinkCardVaultItemSpec, KernelPaymentRequestVaultItemSpecParam] diff --git a/src/kernel/types/vaults/payment_request_vault_item_state.py b/src/kernel/types/vaults/payment_request_vault_item_state.py new file mode 100644 index 00000000..016a547b --- /dev/null +++ b/src/kernel/types/vaults/payment_request_vault_item_state.py @@ -0,0 +1,65 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing import TYPE_CHECKING, Dict, List, Union, Optional +from typing_extensions import Literal, Annotated, TypeAlias + +from pydantic import Field as FieldInfo + +from ..._utils import PropertyInfo +from ..._models import BaseModel +from .kernel_card_state import KernelCardState + +__all__ = ["PaymentRequestVaultItemState", "LinkCardState", "LinkCardStateMasks"] + + +class LinkCardStateMasks(BaseModel): + brand: Optional[str] = None + + last4: Optional[str] = None + + token_last4: Optional[str] = None + """Last four digits of the network token presented to the merchant.""" + + if TYPE_CHECKING: + # Some versions of Pydantic <2.8.0 have a bug and don’t allow assigning a + # value to this field, so for compatibility we avoid doing it at runtime. + __pydantic_extra__: Dict[str, str] = FieldInfo(init=False) # pyright: ignore[reportIncompatibleVariableOverride] + + # Stub to indicate that arbitrary properties are accepted. + # To access properties that are not valid identifiers you can use `getattr`, e.g. + # `getattr(obj, '$type')` + def __getattr__(self, attr: str) -> str: ... + else: + __pydantic_extra__: Dict[str, str] + + +class LinkCardState(BaseModel): + """Issued Link cards retain encrypted card material for the fill operation. + + Link cards do not expose aliases or support egress substitution. + """ + + provider: Literal["link"] + + status: Literal[ + "requested", "pending_authorization", "ready", "consumed", "expired", "declined", "recovery_required" + ] + """ + recovery_required means an original provider operation has an unresolved outcome + and the card cannot be used. Reads keep observing a known provider request and + may clear the recovery. To continue, delete this card and create a new one; + deleting cancels the original request when its ID is known and keeps the + recovery evidence. The user may see an approval request for the original card + and should approve only the new one. + """ + + domains: Optional[List[str]] = None + + masks: Optional[LinkCardStateMasks] = None + + status_reason: Optional[str] = None + + +PaymentRequestVaultItemState: TypeAlias = Annotated[ + Union[LinkCardState, KernelCardState], PropertyInfo(discriminator="provider") +] diff --git a/src/kernel/types/vaults/remove_payment_method_vault_item_operation_request_param.py b/src/kernel/types/vaults/remove_payment_method_vault_item_operation_request_param.py new file mode 100644 index 00000000..66cdf81e --- /dev/null +++ b/src/kernel/types/vaults/remove_payment_method_vault_item_operation_request_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["RemovePaymentMethodVaultItemOperationRequestParam"] + + +class RemovePaymentMethodVaultItemOperationRequestParam(TypedDict, total=False): + """ + Remove one payment method from a Kernel wallet, only when the wallet advertises remove_payment_method. Removal deletes the stored card and blocks new purchases, fills and confirmations funded by it without affecting the wallet's other payment methods; the wallet stays connected even with no payment methods left. A purchase funded by the method with an unresolved outcome blocks removal with 409 purchase_unresolved. If the provider outcome is uncertain the method stays in removal_pending and keeps refusing payments; retry the removal later. Removal is not proof that a payment did not occur. Scoped API keys require vaults:write in addition to vaults:use on this vault; otherwise the operation returns 403. + """ + + payment_method_id: Required[str] + """ID from the wallet's payment_methods expansion.""" + + type: Required[Literal["remove_payment_method"]] diff --git a/src/kernel/types/vaults/remove_payment_method_vault_item_operation_result.py b/src/kernel/types/vaults/remove_payment_method_vault_item_operation_result.py new file mode 100644 index 00000000..0ee0040b --- /dev/null +++ b/src/kernel/types/vaults/remove_payment_method_vault_item_operation_result.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["RemovePaymentMethodVaultItemOperationResult"] + + +class RemovePaymentMethodVaultItemOperationResult(BaseModel): + payment_method_id: str + + status: Literal["removed"] + + type: Literal["remove_payment_method"] diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py index 165165fa..f91ece5e 100644 --- a/src/kernel/types/vaults/vault_item.py +++ b/src/kernel/types/vaults/vault_item.py @@ -15,6 +15,7 @@ from .link_shipping_address import LinkShippingAddress from .wallet_vault_item_spec import WalletVaultItemSpec from .wallet_vault_item_state import WalletVaultItemState +from .payment_request_vault_item import PaymentRequestVaultItem from .credential_account_vault_item import CredentialAccountVaultItem __all__ = [ @@ -63,6 +64,8 @@ class WalletVaultItemAvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] @@ -168,6 +171,8 @@ class CardVaultItemAvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] @@ -209,6 +214,6 @@ class CardVaultItem(BaseModel): VaultItem: TypeAlias = Annotated[ - Union[WalletVaultItem, CardVaultItem, CredentialAccountVaultItem, CredentialVaultItem], + Union[WalletVaultItem, CardVaultItem, PaymentRequestVaultItem, CredentialAccountVaultItem, CredentialVaultItem], PropertyInfo(discriminator="type"), ] diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py index dc8c4134..023cc83c 100644 --- a/src/kernel/types/vaults/vault_item_operation_response.py +++ b/src/kernel/types/vaults/vault_item_operation_response.py @@ -14,11 +14,14 @@ from .link_shipping_address import LinkShippingAddress from .wallet_vault_item_spec import WalletVaultItemSpec from .wallet_vault_item_state import WalletVaultItemState +from .payment_request_vault_item import PaymentRequestVaultItem from .credential_account_vault_item import CredentialAccountVaultItem from .fill_vault_item_operation_result import FillVaultItemOperationResult from .passkey_vault_item_operation_result import PasskeyVaultItemOperationResult from .webmcp_invoke_vault_item_operation_result import WebmcpInvokeVaultItemOperationResult from .one_password_fill_vault_item_operation_result import OnePasswordFillVaultItemOperationResult +from .add_payment_method_vault_item_operation_result import AddPaymentMethodVaultItemOperationResult +from .remove_payment_method_vault_item_operation_result import RemovePaymentMethodVaultItemOperationResult __all__ = [ "VaultItemOperationResponse", @@ -66,6 +69,8 @@ class WalletVaultItemAvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] @@ -171,6 +176,8 @@ class CardVaultItemAvailableOperation(BaseModel): "1pw_recover", "1pw_update_access_token", "webmcp_invoke", + "add_payment_method", + "remove_payment_method", ] @@ -214,10 +221,13 @@ class CardVaultItem(BaseModel): VaultItemOperationResponse: TypeAlias = Union[ WalletVaultItem, CardVaultItem, + PaymentRequestVaultItem, CredentialAccountVaultItem, CredentialVaultItem, FillVaultItemOperationResult, PasskeyVaultItemOperationResult, OnePasswordFillVaultItemOperationResult, WebmcpInvokeVaultItemOperationResult, + AddPaymentMethodVaultItemOperationResult, + RemovePaymentMethodVaultItemOperationResult, ] diff --git a/src/kernel/types/vaults/vault_payment_method.py b/src/kernel/types/vaults/vault_payment_method.py index 27f87ad1..6b0d6dc1 100644 --- a/src/kernel/types/vaults/vault_payment_method.py +++ b/src/kernel/types/vaults/vault_payment_method.py @@ -1,10 +1,12 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. from typing import List, Optional +from datetime import datetime +from typing_extensions import Literal from ..._models import BaseModel -__all__ = ["VaultPaymentMethod", "Capabilities", "CapabilitiesSingleUseCard", "Display"] +__all__ = ["VaultPaymentMethod", "Capabilities", "CapabilitiesSingleUseCard", "Display", "Action"] class CapabilitiesSingleUseCard(BaseModel): @@ -30,6 +32,19 @@ class Display(BaseModel): last4: Optional[str] = None +class Action(BaseModel): + name: Literal["card_enrollment"] + + url: str + + capture_token: Optional[str] = None + """Secret bearer capability for embedded card capture with @onkernel/vault-react. + + Present only for Kernel wallets; never for AgentCard. Treat it like the + enrollment URL and do not log or persist it in browser storage. + """ + + class VaultPaymentMethod(BaseModel): id: str @@ -43,9 +58,33 @@ class VaultPaymentMethod(BaseModel): display: Display is_default: bool + """ + For Kernel wallets, true for the default card, ID card, which a Kernel card item + that omits payment_method_id selects. Wallets created with payment methods + enabled have no default card. + """ provider: str """Provider that issued this payment-method ID.""" type: str """Provider-neutral payment-method type normalized to lowercase.""" + + action: Optional[Action] = None + + expires_at: Optional[datetime] = None + """Expiry of a pending enrollment link.""" + + status: Optional[Literal["pending_enrollment", "active", "removal_pending", "recovery_required"]] = None + """Kernel wallets only. + + pending_enrollment means a card_enrollment link is open; active means the card + is stored and can pay when capabilities.single_use_card.eligible is true; + removal_pending means removal started but the provider outcome is unknown, so + retry remove_payment_method; recovery_required means either an enrollment + outcome is unknown (remove the method), or the stored card cannot be read + (contact support; removal is refused with 409). Consult status_reason to + distinguish these cases. Absent for other providers. + """ + + status_reason: Optional[str] = None diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py index 92fa760e..c588ce4c 100644 --- a/tests/api_resources/vaults/test_items.py +++ b/tests/api_resources/vaults/test_items.py @@ -242,6 +242,164 @@ def test_path_params_update_overload_1(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_update_overload_2(self, client: Kernel) -> None: + item = client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_with_all_params_overload_2(self, client: Kernel) -> None: + item = client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + "line_items": [ + { + "name": "name", + "description": "description", + "image_url": "image_url", + "product_url": "product_url", + "quantity": 1, + "sku": "sku", + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + "unit_amount": 0, + "url": "url", + } + ], + "metadata": {"foo": "string"}, + "recurring": { + "interval": "day", + "interval_count": 1, + }, + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_update_overload_2(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_update_overload_2(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_update_overload_2(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.update( + key="x", + id_or_name="", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.update( + key="", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_update_overload_3(self, client: Kernel) -> None: item = client.vaults.items.update( key="x", id_or_name="id_or_name", @@ -253,7 +411,7 @@ def test_method_update_overload_2(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_update_with_all_params_overload_2(self, client: Kernel) -> None: + def test_method_update_with_all_params_overload_3(self, client: Kernel) -> None: item = client.vaults.items.update( key="x", id_or_name="id_or_name", @@ -284,7 +442,7 @@ def test_method_update_with_all_params_overload_2(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_update_overload_2(self, client: Kernel) -> None: + def test_raw_response_update_overload_3(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.update( key="x", id_or_name="id_or_name", @@ -300,7 +458,7 @@ def test_raw_response_update_overload_2(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_update_overload_2(self, client: Kernel) -> None: + def test_streaming_response_update_overload_3(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.update( key="x", id_or_name="id_or_name", @@ -318,7 +476,7 @@ def test_streaming_response_update_overload_2(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_update_overload_2(self, client: Kernel) -> None: + def test_path_params_update_overload_3(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.update( key="x", @@ -1698,6 +1856,125 @@ def test_path_params_perform_operation_overload_15(self, client: Kernel) -> None type="webmcp_invoke", ) + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_perform_operation_overload_16(self, client: Kernel) -> None: + item = client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_perform_operation_overload_16(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_perform_operation_overload_16(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_perform_operation_overload_16(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + type="add_payment_method", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + type="add_payment_method", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_perform_operation_overload_17(self, client: Kernel) -> None: + item = client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + payment_method_id="x", + type="remove_payment_method", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_perform_operation_overload_17(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + payment_method_id="x", + type="remove_payment_method", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_perform_operation_overload_17(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + payment_method_id="x", + type="remove_payment_method", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_perform_operation_overload_17(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + payment_method_id="x", + type="remove_payment_method", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + payment_method_id="x", + type="remove_payment_method", + ) + @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_method_upsert_overload_1(self, client: Kernel) -> None: @@ -1972,19 +2249,177 @@ def test_method_upsert_overload_3(self, client: Kernel) -> None: key="x", id_or_name="id_or_name", spec={ - "authorization": { - "client": {"type": "kernel_managed"}, - "method": "oauth", - }, - "provider": "1password", + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", }, - type="credential_account", + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_upsert_with_all_params_overload_3(self, client: Kernel) -> None: + item = client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + "line_items": [ + { + "name": "name", + "description": "description", + "image_url": "image_url", + "product_url": "product_url", + "quantity": 1, + "sku": "sku", + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + "unit_amount": 0, + "url": "url", + } + ], + "metadata": {"foo": "string"}, + "recurring": { + "interval": "day", + "interval_count": 1, + }, + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + }, + type="payment_request", ) assert_matches_type(VaultItem, item, path=["response"]) @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize def test_raw_response_upsert_overload_3(self, client: Kernel) -> None: + response = client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_streaming_response_upsert_overload_3(self, client: Kernel) -> None: + with client.vaults.items.with_streaming_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_path_params_upsert_overload_3(self, client: Kernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + client.vaults.items.with_raw_response.upsert( + key="", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_method_upsert_overload_4(self, client: Kernel) -> None: + item = client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "authorization": { + "client": {"type": "kernel_managed"}, + "method": "oauth", + }, + "provider": "1password", + }, + type="credential_account", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + def test_raw_response_upsert_overload_4(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", @@ -2005,7 +2440,7 @@ def test_raw_response_upsert_overload_3(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_upsert_overload_3(self, client: Kernel) -> None: + def test_streaming_response_upsert_overload_4(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", @@ -2028,7 +2463,7 @@ def test_streaming_response_upsert_overload_3(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_upsert_overload_3(self, client: Kernel) -> None: + def test_path_params_upsert_overload_4(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.upsert( key="x", @@ -2059,7 +2494,7 @@ def test_path_params_upsert_overload_3(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_overload_4(self, client: Kernel) -> None: + def test_method_upsert_overload_5(self, client: Kernel) -> None: item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -2078,7 +2513,7 @@ def test_method_upsert_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_method_upsert_with_all_params_overload_4(self, client: Kernel) -> None: + def test_method_upsert_with_all_params_overload_5(self, client: Kernel) -> None: item = client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -2103,7 +2538,7 @@ def test_method_upsert_with_all_params_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_raw_response_upsert_overload_4(self, client: Kernel) -> None: + def test_raw_response_upsert_overload_5(self, client: Kernel) -> None: response = client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", @@ -2126,7 +2561,7 @@ def test_raw_response_upsert_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_streaming_response_upsert_overload_4(self, client: Kernel) -> None: + def test_streaming_response_upsert_overload_5(self, client: Kernel) -> None: with client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", @@ -2151,7 +2586,7 @@ def test_streaming_response_upsert_overload_4(self, client: Kernel) -> None: @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - def test_path_params_upsert_overload_4(self, client: Kernel) -> None: + def test_path_params_upsert_overload_5(self, client: Kernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): client.vaults.items.with_raw_response.upsert( key="x", @@ -2409,6 +2844,164 @@ async def test_path_params_update_overload_1(self, async_client: AsyncKernel) -> @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_update_overload_2(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_with_all_params_overload_2(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + "line_items": [ + { + "name": "name", + "description": "description", + "image_url": "image_url", + "product_url": "product_url", + "quantity": 1, + "sku": "sku", + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + "unit_amount": 0, + "url": "url", + } + ], + "metadata": {"foo": "string"}, + "recurring": { + "interval": "day", + "interval_count": 1, + }, + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_update_overload_2(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_update_overload_2(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.update( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_update_overload_2(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.update( + key="x", + id_or_name="", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.update( + key="", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_update_overload_3(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.update( key="x", id_or_name="id_or_name", @@ -2420,7 +3013,7 @@ async def test_method_update_overload_2(self, async_client: AsyncKernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_update_with_all_params_overload_2(self, async_client: AsyncKernel) -> None: + async def test_method_update_with_all_params_overload_3(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.update( key="x", id_or_name="id_or_name", @@ -2451,7 +3044,7 @@ async def test_method_update_with_all_params_overload_2(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_update_overload_2(self, async_client: AsyncKernel) -> None: + async def test_raw_response_update_overload_3(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.update( key="x", id_or_name="id_or_name", @@ -2467,7 +3060,7 @@ async def test_raw_response_update_overload_2(self, async_client: AsyncKernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_update_overload_2(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_update_overload_3(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.update( key="x", id_or_name="id_or_name", @@ -2485,7 +3078,7 @@ async def test_streaming_response_update_overload_2(self, async_client: AsyncKer @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_update_overload_2(self, async_client: AsyncKernel) -> None: + async def test_path_params_update_overload_3(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.update( key="x", @@ -3752,28 +4345,195 @@ async def test_method_perform_operation_with_all_params_overload_15(self, async_ @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + async def test_raw_response_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + bindings=[ + { + "field": "email", + "input_path": "/email", + }, + { + "field": "password", + "input_path": "/password", + }, + ], + browser_id="browser-session-id", + input={ + "email": "bar", + "password": "bar", + }, + page_url="https://accounts.example.com/signin", + tool_ref="opaque-live-tool-ref", + type="webmcp_invoke", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + bindings=[ + { + "field": "email", + "input_path": "/email", + }, + { + "field": "password", + "input_path": "/password", + }, + ], + browser_id="browser-session-id", + input={ + "email": "bar", + "password": "bar", + }, + page_url="https://accounts.example.com/signin", + tool_ref="opaque-live-tool-ref", + type="webmcp_invoke", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + bindings=[ + { + "field": "email", + "input_path": "/email", + }, + { + "field": "password", + "input_path": "/password", + }, + ], + browser_id="browser-session-id", + input={ + "email": "bar", + "password": "bar", + }, + page_url="https://accounts.example.com/signin", + tool_ref="opaque-live-tool-ref", + type="webmcp_invoke", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + bindings=[ + { + "field": "email", + "input_path": "/email", + }, + { + "field": "password", + "input_path": "/password", + }, + ], + browser_id="browser-session-id", + input={ + "email": "bar", + "password": "bar", + }, + page_url="https://accounts.example.com/signin", + tool_ref="opaque-live-tool-ref", + type="webmcp_invoke", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_16(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_perform_operation_overload_16(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_perform_operation_overload_16(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.perform_operation( + key="key", + id_or_name="id_or_name", + type="add_payment_method", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_perform_operation_overload_16(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="key", + id_or_name="", + type="add_payment_method", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.perform_operation( + key="", + id_or_name="id_or_name", + type="add_payment_method", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_perform_operation_overload_17(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.perform_operation( + key="key", + id_or_name="id_or_name", + payment_method_id="x", + type="remove_payment_method", + ) + assert_matches_type(VaultItemOperationResponse, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_perform_operation_overload_17(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="id_or_name", - bindings=[ - { - "field": "email", - "input_path": "/email", - }, - { - "field": "password", - "input_path": "/password", - }, - ], - browser_id="browser-session-id", - input={ - "email": "bar", - "password": "bar", - }, - page_url="https://accounts.example.com/signin", - tool_ref="opaque-live-tool-ref", - type="webmcp_invoke", + payment_method_id="x", + type="remove_payment_method", ) assert response.is_closed is True @@ -3783,28 +4543,12 @@ async def test_raw_response_perform_operation_overload_15(self, async_client: As @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_perform_operation_overload_17(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.perform_operation( key="key", id_or_name="id_or_name", - bindings=[ - { - "field": "email", - "input_path": "/email", - }, - { - "field": "password", - "input_path": "/password", - }, - ], - browser_id="browser-session-id", - input={ - "email": "bar", - "password": "bar", - }, - page_url="https://accounts.example.com/signin", - tool_ref="opaque-live-tool-ref", - type="webmcp_invoke", + payment_method_id="x", + type="remove_payment_method", ) as response: assert not response.is_closed assert response.http_request.headers.get("X-Stainless-Lang") == "python" @@ -3816,53 +4560,21 @@ async def test_streaming_response_perform_operation_overload_15(self, async_clie @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_perform_operation_overload_15(self, async_client: AsyncKernel) -> None: + async def test_path_params_perform_operation_overload_17(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="key", id_or_name="", - bindings=[ - { - "field": "email", - "input_path": "/email", - }, - { - "field": "password", - "input_path": "/password", - }, - ], - browser_id="browser-session-id", - input={ - "email": "bar", - "password": "bar", - }, - page_url="https://accounts.example.com/signin", - tool_ref="opaque-live-tool-ref", - type="webmcp_invoke", + payment_method_id="x", + type="remove_payment_method", ) with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): await async_client.vaults.items.with_raw_response.perform_operation( key="", id_or_name="id_or_name", - bindings=[ - { - "field": "email", - "input_path": "/email", - }, - { - "field": "password", - "input_path": "/password", - }, - ], - browser_id="browser-session-id", - input={ - "email": "bar", - "password": "bar", - }, - page_url="https://accounts.example.com/signin", - tool_ref="opaque-live-tool-ref", - type="webmcp_invoke", + payment_method_id="x", + type="remove_payment_method", ) @pytest.mark.skip(reason="Mock server tests are disabled") @@ -4135,6 +4847,164 @@ async def test_path_params_upsert_overload_2(self, async_client: AsyncKernel) -> @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize async def test_method_upsert_overload_3(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_upsert_with_all_params_overload_3(self, async_client: AsyncKernel) -> None: + item = await async_client.vaults.items.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + "line_items": [ + { + "name": "name", + "description": "description", + "image_url": "image_url", + "product_url": "product_url", + "quantity": 1, + "sku": "sku", + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + "unit_amount": 0, + "url": "url", + } + ], + "metadata": {"foo": "string"}, + "recurring": { + "interval": "day", + "interval_count": 1, + }, + "totals": [ + { + "amount": 0, + "display_text": "display_text", + "type": "type", + } + ], + }, + type="payment_request", + ) + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + response = await async_client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + assert response.is_closed is True + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async with async_client.vaults.items.with_streaming_response.upsert( + key="x", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) as response: + assert not response.is_closed + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + + item = await response.parse() + assert_matches_type(VaultItem, item, path=["response"]) + + assert cast(Any, response.is_closed) is True + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> None: + with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): + await async_client.vaults.items.with_raw_response.upsert( + key="x", + id_or_name="", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + with pytest.raises(ValueError, match=r"Expected a non-empty value for `key` but received ''"): + await async_client.vaults.items.with_raw_response.upsert( + key="", + id_or_name="id_or_name", + spec={ + "amount": 1, + "context": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "currency": "bFx", + "merchant_name": "x", + "merchant_url": "https://example.com", + "payment_method_id": "x", + "provider": "link", + "wallet": "wallet", + }, + type="payment_request", + ) + + @pytest.mark.skip(reason="Mock server tests are disabled") + @parametrize + async def test_method_upsert_overload_4(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -4151,7 +5021,7 @@ async def test_method_upsert_overload_3(self, async_client: AsyncKernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_raw_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", @@ -4172,7 +5042,7 @@ async def test_raw_response_upsert_overload_3(self, async_client: AsyncKernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", @@ -4195,7 +5065,7 @@ async def test_streaming_response_upsert_overload_3(self, async_client: AsyncKer @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> None: + async def test_path_params_upsert_overload_4(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.upsert( key="x", @@ -4226,7 +5096,7 @@ async def test_path_params_upsert_overload_3(self, async_client: AsyncKernel) -> @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_upsert_overload_4(self, async_client: AsyncKernel) -> None: + async def test_method_upsert_overload_5(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -4245,7 +5115,7 @@ async def test_method_upsert_overload_4(self, async_client: AsyncKernel) -> None @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_method_upsert_with_all_params_overload_4(self, async_client: AsyncKernel) -> None: + async def test_method_upsert_with_all_params_overload_5(self, async_client: AsyncKernel) -> None: item = await async_client.vaults.items.upsert( key="x", id_or_name="id_or_name", @@ -4270,7 +5140,7 @@ async def test_method_upsert_with_all_params_overload_4(self, async_client: Asyn @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_raw_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: + async def test_raw_response_upsert_overload_5(self, async_client: AsyncKernel) -> None: response = await async_client.vaults.items.with_raw_response.upsert( key="x", id_or_name="id_or_name", @@ -4293,7 +5163,7 @@ async def test_raw_response_upsert_overload_4(self, async_client: AsyncKernel) - @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_streaming_response_upsert_overload_4(self, async_client: AsyncKernel) -> None: + async def test_streaming_response_upsert_overload_5(self, async_client: AsyncKernel) -> None: async with async_client.vaults.items.with_streaming_response.upsert( key="x", id_or_name="id_or_name", @@ -4318,7 +5188,7 @@ async def test_streaming_response_upsert_overload_4(self, async_client: AsyncKer @pytest.mark.skip(reason="Mock server tests are disabled") @parametrize - async def test_path_params_upsert_overload_4(self, async_client: AsyncKernel) -> None: + async def test_path_params_upsert_overload_5(self, async_client: AsyncKernel) -> None: with pytest.raises(ValueError, match=r"Expected a non-empty value for `id_or_name` but received ''"): await async_client.vaults.items.with_raw_response.upsert( key="x",