Skip to main content

r402_protocol/payment/
payload.rs

1//! Buyer-signed payment authorization.
2
3use serde::{Deserialize, Serialize};
4
5use super::{Extensions, ResourceInfo, V2, Version2};
6
7/// Signed payment authorization sent by the buyer.
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase", deny_unknown_fields)]
10#[non_exhaustive]
11pub struct PaymentPayload<TAccepted, TPayload> {
12    /// Terms the buyer accepted.
13    pub accepted: TAccepted,
14    /// Scheme-specific signed payload.
15    pub payload: TPayload,
16    /// Optional resource metadata copied from the 402 response.
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub resource: Option<ResourceInfo>,
19    /// Protocol version marker (always `2`).
20    pub x402_version: Version2,
21    /// Optional extension payload block.
22    #[serde(default, skip_serializing_if = "Extensions::is_empty")]
23    pub extensions: Extensions,
24}
25
26impl<TAccepted, TPayload> PaymentPayload<TAccepted, TPayload> {
27    /// Constructs a payload from the two required fields.
28    #[must_use]
29    pub fn new(accepted: TAccepted, payload: TPayload) -> Self {
30        Self {
31            accepted,
32            payload,
33            resource: None,
34            x402_version: V2,
35            extensions: Extensions::new(),
36        }
37    }
38
39    /// Attaches optional resource metadata.
40    #[must_use]
41    pub fn with_resource(mut self, resource: ResourceInfo) -> Self {
42        self.resource = Some(resource);
43        self
44    }
45
46    /// Passes through an optional resource.
47    #[must_use]
48    pub fn with_optional_resource(mut self, resource: Option<ResourceInfo>) -> Self {
49        self.resource = resource;
50        self
51    }
52
53    /// Replaces the `extensions` block.
54    #[must_use]
55    pub fn with_extensions(mut self, extensions: Extensions) -> Self {
56        self.extensions = extensions;
57        self
58    }
59}