1use serde::{Deserialize, Serialize};
6
7use crate::client::{Client, Response};
8use crate::ids::PlanId;
9use crate::params::{
10 Deleted, Expand, Expandable, IdOrCreate, List, Metadata, Object, Paginable, RangeQuery,
11 Timestamp,
12};
13use crate::resources::{CreateProduct, Currency, Product};
14
15#[derive(Clone, Debug, Default, Deserialize, Serialize)]
19pub struct Plan {
20 pub id: PlanId,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub active: Option<bool>,
26
27 #[serde(skip_serializing_if = "Option::is_none")]
32 pub aggregate_usage: Option<PlanAggregateUsage>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
38 pub amount: Option<i64>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
44 pub amount_decimal: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
52 pub billing_scheme: Option<PlanBillingScheme>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
58 pub created: Option<Timestamp>,
59
60 #[serde(skip_serializing_if = "Option::is_none")]
64 pub currency: Option<Currency>,
65
66 #[serde(default)]
68 pub deleted: bool,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
74 pub interval: Option<PlanInterval>,
75
76 #[serde(skip_serializing_if = "Option::is_none")]
80 pub interval_count: Option<u64>,
81
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub livemode: Option<bool>,
85
86 #[serde(skip_serializing_if = "Option::is_none")]
90 pub metadata: Option<Metadata>,
91
92 #[serde(skip_serializing_if = "Option::is_none")]
94 pub nickname: Option<String>,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub product: Option<Expandable<Product>>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
105 pub tiers: Option<Vec<PlanTier>>,
106
107 #[serde(skip_serializing_if = "Option::is_none")]
112 pub tiers_mode: Option<PlanTiersMode>,
113
114 #[serde(skip_serializing_if = "Option::is_none")]
118 pub transform_usage: Option<TransformUsage>,
119
120 #[serde(skip_serializing_if = "Option::is_none")]
122 pub trial_period_days: Option<u32>,
123
124 #[serde(skip_serializing_if = "Option::is_none")]
131 pub usage_type: Option<PlanUsageType>,
132}
133
134impl Plan {
135 pub fn list(client: &Client, params: &ListPlans<'_>) -> Response<List<Plan>> {
137 client.get_query("/plans", params)
138 }
139
140 pub fn retrieve(client: &Client, id: &PlanId, expand: &[&str]) -> Response<Plan> {
142 client.get_query(&format!("/plans/{}", id), Expand { expand })
143 }
144
145 pub fn update(client: &Client, id: &PlanId, params: UpdatePlan<'_>) -> Response<Plan> {
150 #[allow(clippy::needless_borrows_for_generic_args)]
151 client.post_form(&format!("/plans/{}", id), ¶ms)
152 }
153
154 pub fn delete(client: &Client, id: &PlanId) -> Response<Deleted<PlanId>> {
158 client.delete(&format!("/plans/{}", id))
159 }
160}
161
162impl Object for Plan {
163 type Id = PlanId;
164 fn id(&self) -> Self::Id {
165 self.id.clone()
166 }
167 fn object(&self) -> &'static str {
168 "plan"
169 }
170}
171
172#[derive(Clone, Debug, Default, Deserialize, Serialize)]
173pub struct PlanTier {
174 pub flat_amount: Option<i64>,
176
177 pub flat_amount_decimal: Option<String>,
179
180 pub unit_amount: Option<i64>,
182
183 pub unit_amount_decimal: Option<String>,
185
186 pub up_to: Option<i64>,
188}
189
190#[derive(Clone, Debug, Default, Deserialize, Serialize)]
191pub struct TransformUsage {
192 pub divide_by: i64,
194
195 pub round: TransformUsageRound,
197}
198
199#[derive(Clone, Debug, Serialize, Default)]
201pub struct ListPlans<'a> {
202 #[serde(skip_serializing_if = "Option::is_none")]
204 pub active: Option<bool>,
205
206 #[serde(skip_serializing_if = "Option::is_none")]
210 pub created: Option<RangeQuery<Timestamp>>,
211
212 #[serde(skip_serializing_if = "Option::is_none")]
217 pub ending_before: Option<PlanId>,
218
219 #[serde(skip_serializing_if = "Expand::is_empty")]
221 pub expand: &'a [&'a str],
222
223 #[serde(skip_serializing_if = "Option::is_none")]
227 pub limit: Option<u64>,
228
229 #[serde(skip_serializing_if = "Option::is_none")]
231 pub product: Option<IdOrCreate<'a, CreateProduct<'a>>>,
232
233 #[serde(skip_serializing_if = "Option::is_none")]
238 pub starting_after: Option<PlanId>,
239}
240
241impl<'a> ListPlans<'a> {
242 pub fn new() -> Self {
243 ListPlans {
244 active: Default::default(),
245 created: Default::default(),
246 ending_before: Default::default(),
247 expand: Default::default(),
248 limit: Default::default(),
249 product: Default::default(),
250 starting_after: Default::default(),
251 }
252 }
253}
254impl Paginable for ListPlans<'_> {
255 type O = Plan;
256 fn set_last(&mut self, item: Self::O) {
257 self.starting_after = Some(item.id());
258 }
259}
260#[derive(Clone, Debug, Serialize, Default)]
262pub struct UpdatePlan<'a> {
263 #[serde(skip_serializing_if = "Option::is_none")]
265 pub active: Option<bool>,
266
267 #[serde(skip_serializing_if = "Expand::is_empty")]
269 pub expand: &'a [&'a str],
270
271 #[serde(skip_serializing_if = "Option::is_none")]
277 pub metadata: Option<Metadata>,
278
279 #[serde(skip_serializing_if = "Option::is_none")]
281 pub nickname: Option<&'a str>,
282
283 #[serde(skip_serializing_if = "Option::is_none")]
287 pub product: Option<IdOrCreate<'a, CreateProduct<'a>>>,
288
289 #[serde(skip_serializing_if = "Option::is_none")]
291 pub trial_period_days: Option<u32>,
292}
293
294impl<'a> UpdatePlan<'a> {
295 pub fn new() -> Self {
296 UpdatePlan {
297 active: Default::default(),
298 expand: Default::default(),
299 metadata: Default::default(),
300 nickname: Default::default(),
301 product: Default::default(),
302 trial_period_days: Default::default(),
303 }
304 }
305}
306
307#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
309#[serde(rename_all = "snake_case")]
310pub enum PlanAggregateUsage {
311 LastDuringPeriod,
312 LastEver,
313 Max,
314 Sum,
315}
316
317impl PlanAggregateUsage {
318 pub fn as_str(self) -> &'static str {
319 match self {
320 PlanAggregateUsage::LastDuringPeriod => "last_during_period",
321 PlanAggregateUsage::LastEver => "last_ever",
322 PlanAggregateUsage::Max => "max",
323 PlanAggregateUsage::Sum => "sum",
324 }
325 }
326}
327
328impl AsRef<str> for PlanAggregateUsage {
329 fn as_ref(&self) -> &str {
330 self.as_str()
331 }
332}
333
334impl std::fmt::Display for PlanAggregateUsage {
335 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
336 self.as_str().fmt(f)
337 }
338}
339impl std::default::Default for PlanAggregateUsage {
340 fn default() -> Self {
341 Self::LastDuringPeriod
342 }
343}
344
345#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
347#[serde(rename_all = "snake_case")]
348pub enum PlanBillingScheme {
349 PerUnit,
350 Tiered,
351}
352
353impl PlanBillingScheme {
354 pub fn as_str(self) -> &'static str {
355 match self {
356 PlanBillingScheme::PerUnit => "per_unit",
357 PlanBillingScheme::Tiered => "tiered",
358 }
359 }
360}
361
362impl AsRef<str> for PlanBillingScheme {
363 fn as_ref(&self) -> &str {
364 self.as_str()
365 }
366}
367
368impl std::fmt::Display for PlanBillingScheme {
369 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
370 self.as_str().fmt(f)
371 }
372}
373impl std::default::Default for PlanBillingScheme {
374 fn default() -> Self {
375 Self::PerUnit
376 }
377}
378
379#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
381#[serde(rename_all = "snake_case")]
382pub enum PlanInterval {
383 Day,
384 Month,
385 Week,
386 Year,
387}
388
389impl PlanInterval {
390 pub fn as_str(self) -> &'static str {
391 match self {
392 PlanInterval::Day => "day",
393 PlanInterval::Month => "month",
394 PlanInterval::Week => "week",
395 PlanInterval::Year => "year",
396 }
397 }
398}
399
400impl AsRef<str> for PlanInterval {
401 fn as_ref(&self) -> &str {
402 self.as_str()
403 }
404}
405
406impl std::fmt::Display for PlanInterval {
407 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
408 self.as_str().fmt(f)
409 }
410}
411impl std::default::Default for PlanInterval {
412 fn default() -> Self {
413 Self::Day
414 }
415}
416
417#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
419#[serde(rename_all = "snake_case")]
420pub enum PlanTiersMode {
421 Graduated,
422 Volume,
423}
424
425impl PlanTiersMode {
426 pub fn as_str(self) -> &'static str {
427 match self {
428 PlanTiersMode::Graduated => "graduated",
429 PlanTiersMode::Volume => "volume",
430 }
431 }
432}
433
434impl AsRef<str> for PlanTiersMode {
435 fn as_ref(&self) -> &str {
436 self.as_str()
437 }
438}
439
440impl std::fmt::Display for PlanTiersMode {
441 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
442 self.as_str().fmt(f)
443 }
444}
445impl std::default::Default for PlanTiersMode {
446 fn default() -> Self {
447 Self::Graduated
448 }
449}
450
451#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
453#[serde(rename_all = "snake_case")]
454pub enum PlanUsageType {
455 Licensed,
456 Metered,
457}
458
459impl PlanUsageType {
460 pub fn as_str(self) -> &'static str {
461 match self {
462 PlanUsageType::Licensed => "licensed",
463 PlanUsageType::Metered => "metered",
464 }
465 }
466}
467
468impl AsRef<str> for PlanUsageType {
469 fn as_ref(&self) -> &str {
470 self.as_str()
471 }
472}
473
474impl std::fmt::Display for PlanUsageType {
475 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
476 self.as_str().fmt(f)
477 }
478}
479impl std::default::Default for PlanUsageType {
480 fn default() -> Self {
481 Self::Licensed
482 }
483}
484
485#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
487#[serde(rename_all = "snake_case")]
488pub enum TransformUsageRound {
489 Down,
490 Up,
491}
492
493impl TransformUsageRound {
494 pub fn as_str(self) -> &'static str {
495 match self {
496 TransformUsageRound::Down => "down",
497 TransformUsageRound::Up => "up",
498 }
499 }
500}
501
502impl AsRef<str> for TransformUsageRound {
503 fn as_ref(&self) -> &str {
504 self.as_str()
505 }
506}
507
508impl std::fmt::Display for TransformUsageRound {
509 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
510 self.as_str().fmt(f)
511 }
512}
513impl std::default::Default for TransformUsageRound {
514 fn default() -> Self {
515 Self::Down
516 }
517}