1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Deserialize, Serialize)]
4#[serde(rename_all = "camelCase")]
5pub struct InitializeRequest {}
6
7#[derive(Debug, Clone, Default, Deserialize, Serialize)]
8#[serde(rename_all = "camelCase")]
9pub struct InitializeResponse {
10 pub success: bool,
11}
12
13#[derive(Debug, Deserialize, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub struct GetProductsRequest {
16 pub product_ids: Vec<String>,
17 #[serde(default = "default_product_type")]
18 pub product_type: String,
19}
20
21fn default_product_type() -> String {
22 "subs".to_string()
23}
24
25#[derive(Debug, Clone, Deserialize, Serialize)]
26#[serde(rename_all = "camelCase")]
27pub struct PricingPhase {
28 pub formatted_price: String,
29 pub price_currency_code: String,
30 pub price_amount_micros: i64,
31 pub billing_period: String,
32 pub billing_cycle_count: i32,
33 pub recurrence_mode: i32,
34}
35
36#[derive(Debug, Clone, Deserialize, Serialize)]
37#[serde(rename_all = "camelCase")]
38pub struct SubscriptionOffer {
39 pub offer_token: String,
40 pub base_plan_id: String,
41 pub offer_id: Option<String>,
42 pub pricing_phases: Vec<PricingPhase>,
43}
44
45#[derive(Debug, Clone, Deserialize, Serialize)]
46#[serde(rename_all = "camelCase")]
47pub struct Product {
48 pub product_id: String,
49 pub title: String,
50 pub description: String,
51 pub product_type: String,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub formatted_price: Option<String>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub price_currency_code: Option<String>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub price_amount_micros: Option<i64>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub subscription_offer_details: Option<Vec<SubscriptionOffer>>,
60}
61
62#[derive(Debug, Clone, Deserialize, Serialize)]
63#[serde(rename_all = "camelCase")]
64pub struct GetProductsResponse {
65 pub products: Vec<Product>,
66}
67
68#[derive(Debug, Deserialize, Serialize)]
69#[serde(rename_all = "camelCase")]
70pub struct PurchaseRequest {
71 pub product_id: String,
72 #[serde(default = "default_product_type")]
73 pub product_type: String,
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub offer_token: Option<String>,
76}
77
78#[derive(Debug, Clone, Deserialize, Serialize)]
79#[serde(rename_all = "camelCase")]
80pub struct Purchase {
81 pub order_id: Option<String>,
82 pub package_name: String,
83 pub product_id: String,
84 pub purchase_time: i64,
85 pub purchase_token: String,
86 pub purchase_state: i32,
87 pub is_auto_renewing: bool,
88 pub is_acknowledged: bool,
89 pub original_json: String,
90 pub signature: String,
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize)]
94#[serde(rename_all = "camelCase")]
95pub struct RestorePurchasesRequest {
96 #[serde(default = "default_product_type")]
97 pub product_type: String,
98}
99
100#[derive(Debug, Clone, Deserialize, Serialize)]
101#[serde(rename_all = "camelCase")]
102pub struct RestorePurchasesResponse {
103 pub purchases: Vec<Purchase>,
104}
105
106#[derive(Debug, Clone, Deserialize, Serialize)]
107#[serde(rename_all = "camelCase")]
108pub struct PurchaseHistoryRecord {
109 pub product_id: String,
110 pub purchase_time: i64,
111 pub purchase_token: String,
112 pub quantity: i32,
113 pub original_json: String,
114 pub signature: String,
115}
116
117#[derive(Debug, Clone, Deserialize, Serialize)]
118#[serde(rename_all = "camelCase")]
119pub struct GetPurchaseHistoryResponse {
120 pub history: Vec<PurchaseHistoryRecord>,
121}
122
123#[derive(Debug, Deserialize, Serialize)]
124#[serde(rename_all = "camelCase")]
125pub struct AcknowledgePurchaseRequest {
126 pub purchase_token: String,
127}
128
129#[derive(Debug, Clone, Deserialize, Serialize)]
130#[serde(rename_all = "camelCase")]
131pub struct AcknowledgePurchaseResponse {
132 pub success: bool,
133}
134
135#[derive(Debug, Clone, Copy, PartialEq)]
136pub enum PurchaseStateValue {
137 Purchased = 0,
138 Canceled = 1,
139 Pending = 2,
140}
141
142impl Serialize for PurchaseStateValue {
143 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
144 where
145 S: serde::Serializer,
146 {
147 serializer.serialize_i32(*self as i32)
148 }
149}
150
151impl<'de> Deserialize<'de> for PurchaseStateValue {
152 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
153 where
154 D: serde::Deserializer<'de>,
155 {
156 let value = i32::deserialize(deserializer)?;
157 match value {
158 0 => Ok(PurchaseStateValue::Purchased),
159 1 => Ok(PurchaseStateValue::Canceled),
160 2 => Ok(PurchaseStateValue::Pending),
161 _ => Err(serde::de::Error::custom(format!(
162 "Invalid purchase state: {}",
163 value
164 ))),
165 }
166 }
167}
168
169#[derive(Debug, Deserialize, Serialize)]
170#[serde(rename_all = "camelCase")]
171pub struct GetProductStatusRequest {
172 pub product_id: String,
173 #[serde(default = "default_product_type")]
174 pub product_type: String,
175}
176
177#[derive(Debug, Clone, Deserialize, Serialize)]
178#[serde(rename_all = "camelCase")]
179pub struct ProductStatus {
180 pub product_id: String,
181 pub is_owned: bool,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub purchase_state: Option<PurchaseStateValue>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub purchase_time: Option<i64>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub expiration_time: Option<i64>,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 pub is_auto_renewing: Option<bool>,
190 #[serde(skip_serializing_if = "Option::is_none")]
191 pub is_acknowledged: Option<bool>,
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub purchase_token: Option<String>,
194}