Skip to content

Commit fc4b0de

Browse files
feat: Complete Visa vault verification and transaction reporting
Stainless-Generated-From: 95755eb52964f48e3ecbcb51119caf08834cc53f
1 parent efa6445 commit fc4b0de

12 files changed

Lines changed: 484 additions & 84 deletions

‎api.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ from kernel.types.vaults import (
571571
CardVaultItemSpec,
572572
CardVaultItemState,
573573
CollectVaultItemOperationRequest,
574+
ConfirmTransactionVaultItemOperationRequest,
574575
CredentialAccountVaultItem,
575576
CredentialAccountVaultItemRequest,
576577
CredentialCollectionAction,

‎src/kernel/resources/vaults/items.py‎

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,66 @@ def perform_operation(
440440
"""
441441
...
442442

443+
@overload
444+
def perform_operation(
445+
self,
446+
key: str,
447+
*,
448+
id_or_name: str,
449+
amount: int,
450+
currency: str,
451+
occurred_at: Union[str, datetime],
452+
status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"],
453+
transaction_type: Literal[
454+
"PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"
455+
],
456+
type: Literal["confirm_transaction"],
457+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
458+
# The extra values given here take precedence over values defined on the client or passed to this method.
459+
extra_headers: Headers | None = None,
460+
extra_query: Query | None = None,
461+
extra_body: Body | None = None,
462+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
463+
) -> VaultItemOperationResponse:
464+
"""
465+
Retrieve the item first and invoke only an operation listed in
466+
`available_operations`, following its natural-language description. Availability
467+
is rechecked at execution time; unavailable operations return 409. Authorization
468+
and preparation may call an external provider and return updated state. Link
469+
cards advertise authorize without checkout context. Eligible unused AgentCard
470+
cards advertise prepare_checkout, which requires checkout context and obtains
471+
device approval before native Square Pay. Keep the returned approval page open,
472+
poll until ready_to_submit, then submit before preparation.expires_at. Unused
473+
preparations expire automatically and cannot be reused. If spend-request
474+
creation is rejected with a non-retryable provider error, the card item is
475+
deleted and the provider's error code and message are returned. Rate limits
476+
return HTTP 429 and retain the card item; stop, back off, and retry the same
477+
authorize operation.
478+
479+
Fill returns a value-free execution result. Validation failures before writing
480+
return 400 (invalid request or targets), 403 (access or destination denied), 404
481+
(resource not found), or 409 (item or browser not ready). Once writing starts,
482+
known partial failures and indeterminate field outcomes return 200 with status
483+
`failed` or `unknown`. Fill never submits the page, so it is safe to retry after
484+
a failure, an `unknown` outcome, or a transport error.
485+
486+
Args:
487+
amount: Actual transaction amount in minor units, no greater than the approved limit.
488+
489+
currency: Must match the approved purchase currency.
490+
491+
occurred_at: Time the merchant outcome was observed.
492+
493+
extra_headers: Send extra headers
494+
495+
extra_query: Add additional query parameters to the request
496+
497+
extra_body: Add additional JSON properties to the request
498+
499+
timeout: Override the client-level default timeout for this request, in seconds
500+
"""
501+
...
502+
443503
@overload
444504
def perform_operation(
445505
self,
@@ -928,6 +988,7 @@ def perform_operation(
928988

929989
@required_args(
930990
["id_or_name", "type"],
991+
["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"],
931992
["id_or_name", "checkout", "type"],
932993
["id_or_name", "browser_id", "fields", "type"],
933994
["id_or_name", "browser_id", "page_url", "type"],
@@ -940,6 +1001,7 @@ def perform_operation(
9401001
*,
9411002
id_or_name: str,
9421003
type: Literal["authorize"]
1004+
| Literal["confirm_transaction"]
9431005
| Literal["collect"]
9441006
| Literal["prepare_checkout"]
9451007
| Literal["fill"]
@@ -949,6 +1011,14 @@ def perform_operation(
9491011
| Literal["1pw_recover"]
9501012
| Literal["1pw_update_access_token"]
9511013
| Literal["webmcp_invoke"],
1014+
amount: int | Omit = omit,
1015+
currency: str | Omit = omit,
1016+
occurred_at: Union[str, datetime] | Omit = omit,
1017+
status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"] | Omit = omit,
1018+
transaction_type: Literal[
1019+
"PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"
1020+
]
1021+
| Omit = omit,
9521022
checkout: VaultCheckoutContextParam | Omit = omit,
9531023
browser_id: str | Omit = omit,
9541024
fields: Iterable[VaultFillFieldParam] | Omit = omit,
@@ -983,6 +1053,11 @@ def perform_operation(
9831053
body=maybe_transform(
9841054
{
9851055
"type": type,
1056+
"amount": amount,
1057+
"currency": currency,
1058+
"occurred_at": occurred_at,
1059+
"status": status,
1060+
"transaction_type": transaction_type,
9861061
"checkout": checkout,
9871062
"browser_id": browser_id,
9881063
"fields": fields,
@@ -1614,6 +1689,66 @@ async def perform_operation(
16141689
"""
16151690
...
16161691

1692+
@overload
1693+
async def perform_operation(
1694+
self,
1695+
key: str,
1696+
*,
1697+
id_or_name: str,
1698+
amount: int,
1699+
currency: str,
1700+
occurred_at: Union[str, datetime],
1701+
status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"],
1702+
transaction_type: Literal[
1703+
"PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"
1704+
],
1705+
type: Literal["confirm_transaction"],
1706+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1707+
# The extra values given here take precedence over values defined on the client or passed to this method.
1708+
extra_headers: Headers | None = None,
1709+
extra_query: Query | None = None,
1710+
extra_body: Body | None = None,
1711+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
1712+
) -> VaultItemOperationResponse:
1713+
"""
1714+
Retrieve the item first and invoke only an operation listed in
1715+
`available_operations`, following its natural-language description. Availability
1716+
is rechecked at execution time; unavailable operations return 409. Authorization
1717+
and preparation may call an external provider and return updated state. Link
1718+
cards advertise authorize without checkout context. Eligible unused AgentCard
1719+
cards advertise prepare_checkout, which requires checkout context and obtains
1720+
device approval before native Square Pay. Keep the returned approval page open,
1721+
poll until ready_to_submit, then submit before preparation.expires_at. Unused
1722+
preparations expire automatically and cannot be reused. If spend-request
1723+
creation is rejected with a non-retryable provider error, the card item is
1724+
deleted and the provider's error code and message are returned. Rate limits
1725+
return HTTP 429 and retain the card item; stop, back off, and retry the same
1726+
authorize operation.
1727+
1728+
Fill returns a value-free execution result. Validation failures before writing
1729+
return 400 (invalid request or targets), 403 (access or destination denied), 404
1730+
(resource not found), or 409 (item or browser not ready). Once writing starts,
1731+
known partial failures and indeterminate field outcomes return 200 with status
1732+
`failed` or `unknown`. Fill never submits the page, so it is safe to retry after
1733+
a failure, an `unknown` outcome, or a transport error.
1734+
1735+
Args:
1736+
amount: Actual transaction amount in minor units, no greater than the approved limit.
1737+
1738+
currency: Must match the approved purchase currency.
1739+
1740+
occurred_at: Time the merchant outcome was observed.
1741+
1742+
extra_headers: Send extra headers
1743+
1744+
extra_query: Add additional query parameters to the request
1745+
1746+
extra_body: Add additional JSON properties to the request
1747+
1748+
timeout: Override the client-level default timeout for this request, in seconds
1749+
"""
1750+
...
1751+
16171752
@overload
16181753
async def perform_operation(
16191754
self,
@@ -2102,6 +2237,7 @@ async def perform_operation(
21022237

21032238
@required_args(
21042239
["id_or_name", "type"],
2240+
["id_or_name", "amount", "currency", "occurred_at", "status", "transaction_type", "type"],
21052241
["id_or_name", "checkout", "type"],
21062242
["id_or_name", "browser_id", "fields", "type"],
21072243
["id_or_name", "browser_id", "page_url", "type"],
@@ -2114,6 +2250,7 @@ async def perform_operation(
21142250
*,
21152251
id_or_name: str,
21162252
type: Literal["authorize"]
2253+
| Literal["confirm_transaction"]
21172254
| Literal["collect"]
21182255
| Literal["prepare_checkout"]
21192256
| Literal["fill"]
@@ -2123,6 +2260,14 @@ async def perform_operation(
21232260
| Literal["1pw_recover"]
21242261
| Literal["1pw_update_access_token"]
21252262
| Literal["webmcp_invoke"],
2263+
amount: int | Omit = omit,
2264+
currency: str | Omit = omit,
2265+
occurred_at: Union[str, datetime] | Omit = omit,
2266+
status: Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"] | Omit = omit,
2267+
transaction_type: Literal[
2268+
"PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"
2269+
]
2270+
| Omit = omit,
21262271
checkout: VaultCheckoutContextParam | Omit = omit,
21272272
browser_id: str | Omit = omit,
21282273
fields: Iterable[VaultFillFieldParam] | Omit = omit,
@@ -2157,6 +2302,11 @@ async def perform_operation(
21572302
body=await async_maybe_transform(
21582303
{
21592304
"type": type,
2305+
"amount": amount,
2306+
"currency": currency,
2307+
"occurred_at": occurred_at,
2308+
"status": status,
2309+
"transaction_type": transaction_type,
21602310
"checkout": checkout,
21612311
"browser_id": browser_id,
21622312
"fields": fields,

‎src/kernel/types/vaults/__init__.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@
113113
from .one_password_fill_vault_item_operation_request_param import (
114114
OnePasswordFillVaultItemOperationRequestParam as OnePasswordFillVaultItemOperationRequestParam,
115115
)
116+
from .confirm_transaction_vault_item_operation_request_param import (
117+
ConfirmTransactionVaultItemOperationRequestParam as ConfirmTransactionVaultItemOperationRequestParam,
118+
)
116119
from .one_password_recover_vault_item_operation_request_param import (
117120
OnePasswordRecoverVaultItemOperationRequestParam as OnePasswordRecoverVaultItemOperationRequestParam,
118121
)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import Union
6+
from datetime import datetime
7+
from typing_extensions import Literal, Required, Annotated, TypedDict
8+
9+
from ..._utils import PropertyInfo
10+
11+
__all__ = ["ConfirmTransactionVaultItemOperationRequestParam"]
12+
13+
14+
class ConfirmTransactionVaultItemOperationRequestParam(TypedDict, total=False):
15+
"""Report a real merchant transaction outcome for an issued Kernel Visa credential.
16+
17+
Never infer success from filling checkout or receiving a credential. Supply the observed status, transaction type, actual amount, currency and timestamp. Unknown outcomes require manual reconciliation, not retry. Each purchase accepts one report.
18+
"""
19+
20+
amount: Required[int]
21+
"""Actual transaction amount in minor units, no greater than the approved limit."""
22+
23+
currency: Required[str]
24+
"""Must match the approved purchase currency."""
25+
26+
occurred_at: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]]
27+
"""Time the merchant outcome was observed."""
28+
29+
status: Required[Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"]]
30+
31+
transaction_type: Required[
32+
Literal["PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"]
33+
]
34+
35+
type: Required[Literal["confirm_transaction"]]

‎src/kernel/types/vaults/credential_account_vault_item.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class AvailableOperation(BaseModel):
3232

3333
type: Literal[
3434
"authorize",
35+
"confirm_transaction",
3536
"collect",
3637
"prepare_checkout",
3738
"fill",

‎src/kernel/types/vaults/credential_vault_item.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class AvailableOperation(BaseModel):
3939

4040
type: Literal[
4141
"authorize",
42+
"confirm_transaction",
4243
"collect",
4344
"prepare_checkout",
4445
"fill",

‎src/kernel/types/vaults/item_perform_operation_params.py‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
__all__ = [
1616
"ItemPerformOperationParams",
1717
"AuthorizeVaultItemOperationRequest",
18+
"ConfirmTransactionVaultItemOperationRequest",
1819
"CollectVaultItemOperationRequest",
1920
"PrepareCheckoutVaultItemOperationRequest",
2021
"FillVaultItemOperationRequest",
@@ -33,6 +34,27 @@ class AuthorizeVaultItemOperationRequest(TypedDict, total=False):
3334
type: Required[Literal["authorize"]]
3435

3536

37+
class ConfirmTransactionVaultItemOperationRequest(TypedDict, total=False):
38+
id_or_name: Required[str]
39+
40+
amount: Required[int]
41+
"""Actual transaction amount in minor units, no greater than the approved limit."""
42+
43+
currency: Required[str]
44+
"""Must match the approved purchase currency."""
45+
46+
occurred_at: Required[Annotated[Union[str, datetime], PropertyInfo(format="iso8601")]]
47+
"""Time the merchant outcome was observed."""
48+
49+
status: Required[Literal["APPROVED", "DECLINED", "PENDING", "ERROR", "CANCELLED"]]
50+
51+
transaction_type: Required[
52+
Literal["PURCHASE", "AUTHORIZATION", "CAPTURE", "REFUND", "REVERSAL", "VERIFICATION", "CHARGEBACK", "FRAUD"]
53+
]
54+
55+
type: Required[Literal["confirm_transaction"]]
56+
57+
3658
class CollectVaultItemOperationRequest(TypedDict, total=False):
3759
id_or_name: Required[str]
3860

@@ -173,6 +195,7 @@ class WebmcpInvokeVaultItemOperationRequest(TypedDict, total=False):
173195

174196
ItemPerformOperationParams: TypeAlias = Union[
175197
AuthorizeVaultItemOperationRequest,
198+
ConfirmTransactionVaultItemOperationRequest,
176199
CollectVaultItemOperationRequest,
177200
PrepareCheckoutVaultItemOperationRequest,
178201
FillVaultItemOperationRequest,

‎src/kernel/types/vaults/kernel_card_vault_item_spec.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,15 @@ class KernelCardVaultItemSpec(BaseModel):
3737
wallet: str
3838
"""Key of the Kernel wallet item whose enrolled card pays."""
3939

40+
merchant_category: Optional[str] = None
41+
"""Actual merchant category when known. Omit rather than invent a category."""
42+
43+
merchant_category_code: Optional[str] = None
44+
"""Actual merchant MCC when known.
45+
46+
Omit rather than invent a code. 0000 is not accepted.
47+
"""
48+
4049
merchant_country: Optional[str] = None
4150
"""The merchant's ISO 3166-1 alpha-2 country code.
4251

‎src/kernel/types/vaults/kernel_card_vault_item_spec_param.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ class KernelCardVaultItemSpecParam(TypedDict, total=False):
3636
wallet: Required[str]
3737
"""Key of the Kernel wallet item whose enrolled card pays."""
3838

39+
merchant_category: str
40+
"""Actual merchant category when known. Omit rather than invent a category."""
41+
42+
merchant_category_code: str
43+
"""Actual merchant MCC when known.
44+
45+
Omit rather than invent a code. 0000 is not accepted.
46+
"""
47+
3948
merchant_country: str
4049
"""The merchant's ISO 3166-1 alpha-2 country code.
4150

‎src/kernel/types/vaults/vault_item.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class WalletVaultItemAvailableOperation(BaseModel):
4747

4848
type: Literal[
4949
"authorize",
50+
"confirm_transaction",
5051
"collect",
5152
"prepare_checkout",
5253
"fill",
@@ -122,6 +123,7 @@ class CardVaultItemAvailableOperation(BaseModel):
122123

123124
type: Literal[
124125
"authorize",
126+
"confirm_transaction",
125127
"collect",
126128
"prepare_checkout",
127129
"fill",

0 commit comments

Comments
 (0)