camel icon indicating copy to clipboard operation
camel copied to clipboard

[Feature Request] Integrate Agent Payments Protocol

Open Wendong-Fan opened this issue 3 months ago • 2 comments

Required prerequisites

  • [x] I have searched the Issue Tracker and Discussions that this hasn't already been reported. (+1 or comment there if it has.)
  • [ ] Consider asking first in a Discussion.

Motivation

Agent Payments Protocol: Building a Secure and Interoperable Future for AI-Driven Payments https://github.com/google-agentic-commerce/AP2

Solution

No response

Alternatives

No response

Additional context

No response

Wendong-Fan avatar Sep 17 '25 22:09 Wendong-Fan

hi guys, would be nice to add a few lines briefing the exact requirement/what module to implement into please, thanks

JINO-ROHIT avatar Nov 03 '25 03:11 JINO-ROHIT

@fengju0213 would help adding more description to this issue

Wendong-Fan avatar Nov 10 '25 05:11 Wendong-Fan

@JINO-ROHIT hi jino,sorry for delayed reply and thanks for your interest The core of AP2 lies in various types of Mandates (Intent / Cart / Payment), which are essentially digitally signed authorization objects.

In CAMEL, we might first define a unified internal representation for them, like this:

from pydantic import BaseModel
from typing import Literal, Dict, Any, Optional, List


class Ap2Mandate(BaseModel):
    id: str
    kind: Literal["intent", "cart", "payment"]
    subject: Dict[str, Any]         
    holder_id: str                  
    signature: Optional[str] = None
    metadata: Dict[str, Any] = {}


class Ap2PaymentRecord(BaseModel):
    id: str
    mandate_id: str
    amount: int
    currency: str
    status: Literal["pending", "succeeded", "failed"]
    raw_response: Dict[str, Any]

then we can add a AP2toolkt Inside the toolkit, you can then call the AP2 service that you’ve set up (you can start by modifying the official sample to make it into a small standalone service).

fengju0213 avatar Nov 25 '25 16:11 fengju0213

@JINO-ROHIT hi jino,sorry for delayed reply and thanks for your interest The core of AP2 lies in various types of Mandates (Intent / Cart / Payment), which are essentially digitally signed authorization objects.

In CAMEL, we might first define a unified internal representation for them, like this:

from pydantic import BaseModel from typing import Literal, Dict, Any, Optional, List

class Ap2Mandate(BaseModel): id: str kind: Literal["intent", "cart", "payment"] subject: Dict[str, Any]
holder_id: str
signature: Optional[str] = None metadata: Dict[str, Any] = {}

class Ap2PaymentRecord(BaseModel): id: str mandate_id: str amount: int currency: str status: Literal["pending", "succeeded", "failed"] raw_response: Dict[str, Any] then we can add a AP2toolkt Inside the toolkit, you can then call the AP2 service that you’ve set up (you can start by modifying the official sample to make it into a small standalone service).

That is nice start, i checked the AP2 mandate, and i generate a sample model here (i am not sure this is a good model), Please review and let us start to talk about this protocol, Thanks

from typing import Literal, Optional, Dict, Any, List
from datetime import datetime



####################  agent identity    ###########################################
class Ap2PublicKey(BaseModel):
    id: str
    alg: Literal["Ed25519", "P-256"]
    public_key: str  # Base64 or Base58


class Ap2Delegation(BaseModel):
    delegated_to: str  # supervisor DID
    scope: List[str]
    expires_at: Optional[str]


class Ap2AgentIdentity(BaseModel):
    did: str
    public_keys: List[Ap2PublicKey]
    policy_claims: Dict[str, any]
    metadata: Dict[str, any]
    delegations: Optional[List[Ap2Delegation]] = None



####################    Payment request   ################################

class Amount(BaseModel):
    value: int
    currency: str  # euro, usd, cny

class Participant(BaseModel):
    payer: str  # DID
    payee: str  # DID

class Terms(BaseModel):
    rail: str  #  x402态sepa态card
    escrow: bool
    dispute_window: Optional[int]  # Dispute Window in days
    additional: Optional[Dict[str, Any]] = {}  

class LineItem(BaseModel):
    sku: str
    price: int
    tax: Optional[int] = 0
    metadata: Optional[Dict[str, Any]] = {}

class PolicyTraceRecord(BaseModel):
    rule_id: str
    result: str  # pass/fail
    note: Optional[str] = None

class PaymentRequest(BaseModel):
    id: str
    amount: Amount
    participants: Participant
    terms: Terms
    line_items: List[LineItem]
    evidence: Optional[List[str]] = []
    policy_trace: Optional[List[PolicyTraceRecord]] = []
    




####################   Settlement Proof   ################################################

class LedgerEntry(BaseModel):
    account: str
    amount: int
    currency: str
    direction: Literal["debit", "credit"]

class SettlementProof(BaseModel):
    intentId: str
    rail: str
    ledgerEntries: List[LedgerEntry]
    hash: str
    signatures: List[str] 
    compliance: Dict[str, Any]  # PCIDSS?



####################   Mandate   ################################################

class IntentMandate(BaseModel):
    id: str
    holder_id: str
    merchant_id: str
    allowed_actions: List[str]
    constraints: Dict[str, Any]  # refound limit, time limit, etc.
    signature: Optional[str]
    metadata: Dict[str, Any] = {}

class CartItem(BaseModel):
    sku: str
    price: int
    quantity: int

class CartMandate(BaseModel):
    id: str
    cart_items: List[CartItem]
    merchant_signature: str
    payment_method: str
    expires_at: datetime
    requires_user_confirmation: bool

class PaymentMandate(BaseModel):
    id: str
    cart_hash: str
    amount: int
    currency: str
    payer_signature: str
    processor_signature: str
    rail: str

zhangchi838596241 avatar Dec 01 '25 23:12 zhangchi838596241

@JINO-ROHIT hi jino,sorry for delayed reply and thanks for your interest The core of AP2 lies in various types of Mandates (Intent / Cart / Payment), which are essentially digitally signed authorization objects. In CAMEL, we might first define a unified internal representation for them, like this: from pydantic import BaseModel from typing import Literal, Dict, Any, Optional, List class Ap2Mandate(BaseModel): id: str kind: Literal["intent", "cart", "payment"] subject: Dict[str, Any] holder_id: str signature: Optional[str] = None metadata: Dict[str, Any] = {} class Ap2PaymentRecord(BaseModel): id: str mandate_id: str amount: int currency: str status: Literal["pending", "succeeded", "failed"] raw_response: Dict[str, Any] then we can add a AP2toolkt Inside the toolkit, you can then call the AP2 service that you’ve set up (you can start by modifying the official sample to make it into a small standalone service).

That is nice start, i checked the AP2 mandate, and i generate a sample model here (i am not sure this is a good model), Please review and let us start to talk about this protocol, Thanks

from typing import Literal, Optional, Dict, Any, List
from datetime import datetime



####################  agent identity    ###########################################
class Ap2PublicKey(BaseModel):
    id: str
    alg: Literal["Ed25519", "P-256"]
    public_key: str  # Base64 or Base58


class Ap2Delegation(BaseModel):
    delegated_to: str  # supervisor DID
    scope: List[str]
    expires_at: Optional[str]


class Ap2AgentIdentity(BaseModel):
    did: str
    public_keys: List[Ap2PublicKey]
    policy_claims: Dict[str, any]
    metadata: Dict[str, any]
    delegations: Optional[List[Ap2Delegation]] = None



####################    Payment request   ################################

class Amount(BaseModel):
    value: int
    currency: str  # euro, usd, cny

class Participant(BaseModel):
    payer: str  # DID
    payee: str  # DID

class Terms(BaseModel):
    rail: str  #  x402态sepa态card
    escrow: bool
    dispute_window: Optional[int]  # Dispute Window in days
    additional: Optional[Dict[str, Any]] = {}  

class LineItem(BaseModel):
    sku: str
    price: int
    tax: Optional[int] = 0
    metadata: Optional[Dict[str, Any]] = {}

class PolicyTraceRecord(BaseModel):
    rule_id: str
    result: str  # pass/fail
    note: Optional[str] = None

class PaymentRequest(BaseModel):
    id: str
    amount: Amount
    participants: Participant
    terms: Terms
    line_items: List[LineItem]
    evidence: Optional[List[str]] = []
    policy_trace: Optional[List[PolicyTraceRecord]] = []
    




####################   Settlement Proof   ################################################

class LedgerEntry(BaseModel):
    account: str
    amount: int
    currency: str
    direction: Literal["debit", "credit"]

class SettlementProof(BaseModel):
    intentId: str
    rail: str
    ledgerEntries: List[LedgerEntry]
    hash: str
    signatures: List[str] 
    compliance: Dict[str, Any]  # PCIDSS?



####################   Mandate   ################################################

class IntentMandate(BaseModel):
    id: str
    holder_id: str
    merchant_id: str
    allowed_actions: List[str]
    constraints: Dict[str, Any]  # refound limit, time limit, etc.
    signature: Optional[str]
    metadata: Dict[str, Any] = {}

class CartItem(BaseModel):
    sku: str
    price: int
    quantity: int

class CartMandate(BaseModel):
    id: str
    cart_items: List[CartItem]
    merchant_signature: str
    payment_method: str
    expires_at: datetime
    requires_user_confirmation: bool

class PaymentMandate(BaseModel):
    id: str
    cart_hash: str
    amount: int
    currency: str
    payer_signature: str
    processor_signature: str
    rail: str

sounds great,lets use this model to quick test!

fengju0213 avatar Dec 02 '25 03:12 fengju0213