Skip to main content

adk_payments/domain/
cart.rs

1use serde::{Deserialize, Serialize};
2
3use crate::domain::{Money, ProtocolExtensions};
4
5/// One authoritative line item in the canonical cart.
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct CartLine {
9    pub line_id: String,
10    #[serde(default, skip_serializing_if = "Option::is_none")]
11    pub merchant_sku: Option<String>,
12    pub title: String,
13    pub quantity: u32,
14    pub unit_price: Money,
15    pub total_price: Money,
16    #[serde(default, skip_serializing_if = "Option::is_none")]
17    pub product_class: Option<String>,
18    #[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
19    pub extensions: ProtocolExtensions,
20}
21
22/// Type of canonical adjustment applied to a cart total.
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "snake_case")]
25pub enum PriceAdjustmentKind {
26    Tax,
27    Shipping,
28    Discount,
29    Fee,
30    Surcharge,
31    Credit,
32    Other(String),
33}
34
35/// Total component outside the primary cart lines.
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37#[serde(rename_all = "camelCase")]
38pub struct PriceAdjustment {
39    pub adjustment_id: String,
40    pub kind: PriceAdjustmentKind,
41    pub label: String,
42    pub amount: Money,
43    #[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
44    pub extensions: ProtocolExtensions,
45}
46
47/// Affiliate or attribution metadata preserved in the canonical cart.
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49#[serde(rename_all = "camelCase")]
50pub struct AffiliateAttribution {
51    pub partner_id: String,
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub campaign_id: Option<String>,
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    pub source: Option<String>,
56    #[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
57    pub extensions: ProtocolExtensions,
58}
59
60/// Canonical cart contents and totals.
61#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct Cart {
64    #[serde(default, skip_serializing_if = "Option::is_none")]
65    pub cart_id: Option<String>,
66    pub lines: Vec<CartLine>,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub subtotal: Option<Money>,
69    #[serde(default, skip_serializing_if = "Vec::is_empty")]
70    pub adjustments: Vec<PriceAdjustment>,
71    pub total: Money,
72    #[serde(default, skip_serializing_if = "Option::is_none")]
73    pub affiliate_attribution: Option<AffiliateAttribution>,
74    #[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
75    pub extensions: ProtocolExtensions,
76}
77
78/// Canonical fulfillment mode.
79#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
80#[serde(rename_all = "snake_case")]
81pub enum FulfillmentKind {
82    Shipping,
83    Pickup,
84    Delivery,
85    Digital,
86    Service,
87    Other(String),
88}
89
90/// Delivery or pickup destination details.
91#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93pub struct FulfillmentDestination {
94    #[serde(default, skip_serializing_if = "Option::is_none")]
95    pub recipient_name: Option<String>,
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub locality: Option<String>,
98    #[serde(default, skip_serializing_if = "Option::is_none")]
99    pub region: Option<String>,
100    #[serde(default, skip_serializing_if = "Option::is_none")]
101    pub country_code: Option<String>,
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub postal_code: Option<String>,
104}
105
106/// Fulfillment choice currently attached to the transaction.
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
108#[serde(rename_all = "camelCase")]
109pub struct FulfillmentSelection {
110    pub fulfillment_id: String,
111    pub kind: FulfillmentKind,
112    pub label: String,
113    #[serde(default, skip_serializing_if = "Option::is_none")]
114    pub amount: Option<Money>,
115    #[serde(default, skip_serializing_if = "Option::is_none")]
116    pub destination: Option<FulfillmentDestination>,
117    #[serde(default)]
118    pub requires_user_selection: bool,
119    #[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
120    pub extensions: ProtocolExtensions,
121}