stripe/resources/generated/
coupon.rs

1// ======================================
2// This file was automatically generated.
3// ======================================
4
5use crate::client::{Client, Response};
6use crate::ids::CouponId;
7use crate::params::{
8    CurrencyMap, Deleted, Expand, List, Metadata, Object, Paginable, RangeQuery, Timestamp,
9};
10use crate::resources::Currency;
11use serde::{Deserialize, Serialize};
12
13/// The resource representing a Stripe "Coupon".
14///
15/// For more details see <https://stripe.com/docs/api/coupons/object>
16#[derive(Clone, Debug, Default, Deserialize, Serialize)]
17pub struct Coupon {
18    /// Unique identifier for the object.
19    pub id: CouponId,
20
21    /// Amount (in the `currency` specified) that will be taken off the subtotal of any invoices for this customer.
22    #[serde(skip_serializing_if = "Option::is_none")]
23    pub amount_off: Option<i64>,
24
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub applies_to: Option<CouponAppliesTo>,
27
28    /// Time at which the object was created.
29    ///
30    /// Measured in seconds since the Unix epoch.
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub created: Option<Timestamp>,
33
34    /// If `amount_off` has been set, the three-letter [ISO code for the currency](https://stripe.com/docs/currencies) of the amount to take off.
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub currency: Option<Currency>,
37
38    /// Coupons defined in each available currency option.
39    ///
40    /// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub currency_options: Option<CurrencyMap<CouponCurrencyOption>>,
43
44    // Always true for a deleted object
45    #[serde(default)]
46    pub deleted: bool,
47
48    /// One of `forever`, `once`, and `repeating`.
49    ///
50    /// Describes how long a customer who applies this coupon will get the discount.
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub duration: Option<CouponDuration>,
53
54    /// If `duration` is `repeating`, the number of months the coupon applies.
55    ///
56    /// Null if coupon `duration` is `forever` or `once`.
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub duration_in_months: Option<i64>,
59
60    /// Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub livemode: Option<bool>,
63
64    /// Maximum number of times this coupon can be redeemed, in total, across all customers, before it is no longer valid.
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub max_redemptions: Option<i64>,
67
68    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
69    ///
70    /// This can be useful for storing additional information about the object in a structured format.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub metadata: Option<Metadata>,
73
74    /// Name of the coupon displayed to customers on for instance invoices or receipts.
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub name: Option<String>,
77
78    /// Percent that will be taken off the subtotal of any invoices for this customer for the duration of the coupon.
79    ///
80    /// For example, a coupon with percent_off of 50 will make a $ (or local equivalent)100 invoice $ (or local equivalent)50 instead.
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub percent_off: Option<f64>,
83
84    /// Date after which the coupon can no longer be redeemed.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub redeem_by: Option<Timestamp>,
87
88    /// Number of times this coupon has been applied to a customer.
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub times_redeemed: Option<i64>,
91
92    /// Taking account of the above properties, whether this coupon can still be applied to a customer.
93    #[serde(skip_serializing_if = "Option::is_none")]
94    pub valid: Option<bool>,
95}
96
97impl Coupon {
98    /// Returns a list of your coupons.
99    pub fn list(client: &Client, params: &ListCoupons<'_>) -> Response<List<Coupon>> {
100        client.get_query("/coupons", params)
101    }
102
103    /// You can create coupons easily via the [coupon management](https://dashboard.stripe.com/coupons) page of the Stripe dashboard.
104    ///
105    /// Coupon creation is also accessible via the API if you need to create coupons on the fly.  A coupon has either a `percent_off` or an `amount_off` and `currency`.
106    /// If you set an `amount_off`, that amount will be subtracted from any invoice’s subtotal.
107    /// For example, an invoice with a subtotal of $100 will have a final total of $0 if a coupon with an `amount_off` of 20000 is applied to it and an invoice with a subtotal of $300 will have a final total of $100 if a coupon with an `amount_off` of 20000 is applied to it.
108    pub fn create(client: &Client, params: CreateCoupon<'_>) -> Response<Coupon> {
109        #[allow(clippy::needless_borrows_for_generic_args)]
110        client.post_form("/coupons", &params)
111    }
112
113    /// Retrieves the coupon with the given ID.
114    pub fn retrieve(client: &Client, id: &CouponId, expand: &[&str]) -> Response<Coupon> {
115        client.get_query(&format!("/coupons/{}", id), Expand { expand })
116    }
117
118    /// Updates the metadata of a coupon.
119    ///
120    /// Other coupon details (currency, duration, amount_off) are, by design, not editable.
121    pub fn update(client: &Client, id: &CouponId, params: UpdateCoupon<'_>) -> Response<Coupon> {
122        #[allow(clippy::needless_borrows_for_generic_args)]
123        client.post_form(&format!("/coupons/{}", id), &params)
124    }
125
126    /// You can delete coupons via the [coupon management](https://dashboard.stripe.com/coupons) page of the Stripe dashboard.
127    ///
128    /// However, deleting a coupon does not affect any customers who have already applied the coupon; it means that new customers can’t redeem the coupon.
129    /// You can also delete coupons via the API.
130    pub fn delete(client: &Client, id: &CouponId) -> Response<Deleted<CouponId>> {
131        client.delete(&format!("/coupons/{}", id))
132    }
133}
134
135impl Object for Coupon {
136    type Id = CouponId;
137    fn id(&self) -> Self::Id {
138        self.id.clone()
139    }
140    fn object(&self) -> &'static str {
141        "coupon"
142    }
143}
144
145#[derive(Clone, Debug, Default, Deserialize, Serialize)]
146pub struct CouponAppliesTo {
147    /// A list of product IDs this coupon applies to.
148    pub products: Vec<String>,
149}
150
151#[derive(Clone, Debug, Default, Deserialize, Serialize)]
152pub struct CouponCurrencyOption {
153    /// Amount (in the `currency` specified) that will be taken off the subtotal of any invoices for this customer.
154    pub amount_off: i64,
155}
156
157/// The parameters for `Coupon::create`.
158#[derive(Clone, Debug, Serialize, Default)]
159pub struct CreateCoupon<'a> {
160    /// A positive integer representing the amount to subtract from an invoice total (required if `percent_off` is not passed).
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub amount_off: Option<i64>,
163
164    /// A hash containing directions for what this Coupon will apply discounts to.
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub applies_to: Option<CreateCouponAppliesTo>,
167
168    /// Three-letter [ISO code for the currency](https://stripe.com/docs/currencies) of the `amount_off` parameter (required if `amount_off` is passed).
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub currency: Option<Currency>,
171
172    /// Coupons defined in each available currency option (only supported if `amount_off` is passed).
173    ///
174    /// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub currency_options: Option<CurrencyMap<CreateCouponCurrencyOptions>>,
177
178    /// Specifies how long the discount will be in effect if used on a subscription.
179    ///
180    /// Defaults to `once`.
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub duration: Option<CouponDuration>,
183
184    /// Required only if `duration` is `repeating`, in which case it must be a positive integer that specifies the number of months the discount will be in effect.
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub duration_in_months: Option<i64>,
187
188    /// Specifies which fields in the response should be expanded.
189    #[serde(skip_serializing_if = "Expand::is_empty")]
190    pub expand: &'a [&'a str],
191
192    /// Unique string of your choice that will be used to identify this coupon when applying it to a customer.
193    ///
194    /// If you don't want to specify a particular code, you can leave the ID blank and we'll generate a random code for you.
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub id: Option<&'a str>,
197
198    /// A positive integer specifying the number of times the coupon can be redeemed before it's no longer valid.
199    ///
200    /// For example, you might have a 50% off coupon that the first 20 readers of your blog can use.
201    #[serde(skip_serializing_if = "Option::is_none")]
202    pub max_redemptions: Option<i64>,
203
204    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
205    ///
206    /// This can be useful for storing additional information about the object in a structured format.
207    /// Individual keys can be unset by posting an empty value to them.
208    /// All keys can be unset by posting an empty value to `metadata`.
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub metadata: Option<Metadata>,
211
212    /// Name of the coupon displayed to customers on, for instance invoices, or receipts.
213    ///
214    /// By default the `id` is shown if `name` is not set.
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub name: Option<&'a str>,
217
218    /// A positive float larger than 0, and smaller or equal to 100, that represents the discount the coupon will apply (required if `amount_off` is not passed).
219    #[serde(skip_serializing_if = "Option::is_none")]
220    pub percent_off: Option<f64>,
221
222    /// Unix timestamp specifying the last time at which the coupon can be redeemed.
223    ///
224    /// After the redeem_by date, the coupon can no longer be applied to new customers.
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub redeem_by: Option<Timestamp>,
227}
228
229impl<'a> CreateCoupon<'a> {
230    pub fn new() -> Self {
231        CreateCoupon {
232            amount_off: Default::default(),
233            applies_to: Default::default(),
234            currency: Default::default(),
235            currency_options: Default::default(),
236            duration: Default::default(),
237            duration_in_months: Default::default(),
238            expand: Default::default(),
239            id: Default::default(),
240            max_redemptions: Default::default(),
241            metadata: Default::default(),
242            name: Default::default(),
243            percent_off: Default::default(),
244            redeem_by: Default::default(),
245        }
246    }
247}
248
249/// The parameters for `Coupon::list`.
250#[derive(Clone, Debug, Serialize, Default)]
251pub struct ListCoupons<'a> {
252    /// A filter on the list, based on the object `created` field.
253    ///
254    /// The value can be a string with an integer Unix timestamp, or it can be a dictionary with a number of different query options.
255    #[serde(skip_serializing_if = "Option::is_none")]
256    pub created: Option<RangeQuery<Timestamp>>,
257
258    /// A cursor for use in pagination.
259    ///
260    /// `ending_before` is an object ID that defines your place in the list.
261    /// For instance, if you make a list request and receive 100 objects, starting with `obj_bar`, your subsequent call can include `ending_before=obj_bar` in order to fetch the previous page of the list.
262    #[serde(skip_serializing_if = "Option::is_none")]
263    pub ending_before: Option<CouponId>,
264
265    /// Specifies which fields in the response should be expanded.
266    #[serde(skip_serializing_if = "Expand::is_empty")]
267    pub expand: &'a [&'a str],
268
269    /// A limit on the number of objects to be returned.
270    ///
271    /// Limit can range between 1 and 100, and the default is 10.
272    #[serde(skip_serializing_if = "Option::is_none")]
273    pub limit: Option<u64>,
274
275    /// A cursor for use in pagination.
276    ///
277    /// `starting_after` is an object ID that defines your place in the list.
278    /// For instance, if you make a list request and receive 100 objects, ending with `obj_foo`, your subsequent call can include `starting_after=obj_foo` in order to fetch the next page of the list.
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub starting_after: Option<CouponId>,
281}
282
283impl<'a> ListCoupons<'a> {
284    pub fn new() -> Self {
285        ListCoupons {
286            created: Default::default(),
287            ending_before: Default::default(),
288            expand: Default::default(),
289            limit: Default::default(),
290            starting_after: Default::default(),
291        }
292    }
293}
294impl Paginable for ListCoupons<'_> {
295    type O = Coupon;
296    fn set_last(&mut self, item: Self::O) {
297        self.starting_after = Some(item.id());
298    }
299}
300/// The parameters for `Coupon::update`.
301#[derive(Clone, Debug, Serialize, Default)]
302pub struct UpdateCoupon<'a> {
303    /// Coupons defined in each available currency option (only supported if the coupon is amount-based).
304    ///
305    /// Each key must be a three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html) and a [supported currency](https://stripe.com/docs/currencies).
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub currency_options: Option<CurrencyMap<UpdateCouponCurrencyOptions>>,
308
309    /// Specifies which fields in the response should be expanded.
310    #[serde(skip_serializing_if = "Expand::is_empty")]
311    pub expand: &'a [&'a str],
312
313    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
314    ///
315    /// This can be useful for storing additional information about the object in a structured format.
316    /// Individual keys can be unset by posting an empty value to them.
317    /// All keys can be unset by posting an empty value to `metadata`.
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub metadata: Option<Metadata>,
320
321    /// Name of the coupon displayed to customers on, for instance invoices, or receipts.
322    ///
323    /// By default the `id` is shown if `name` is not set.
324    #[serde(skip_serializing_if = "Option::is_none")]
325    pub name: Option<&'a str>,
326}
327
328impl<'a> UpdateCoupon<'a> {
329    pub fn new() -> Self {
330        UpdateCoupon {
331            currency_options: Default::default(),
332            expand: Default::default(),
333            metadata: Default::default(),
334            name: Default::default(),
335        }
336    }
337}
338
339#[derive(Clone, Debug, Default, Deserialize, Serialize)]
340pub struct CreateCouponAppliesTo {
341    /// An array of Product IDs that this Coupon will apply to.
342    #[serde(skip_serializing_if = "Option::is_none")]
343    pub products: Option<Vec<String>>,
344}
345
346#[derive(Clone, Debug, Default, Deserialize, Serialize)]
347pub struct CreateCouponCurrencyOptions {
348    /// A positive integer representing the amount to subtract from an invoice total.
349    pub amount_off: i64,
350}
351
352#[derive(Clone, Debug, Default, Deserialize, Serialize)]
353pub struct UpdateCouponCurrencyOptions {
354    /// A positive integer representing the amount to subtract from an invoice total.
355    pub amount_off: i64,
356}
357
358/// An enum representing the possible values of an `Coupon`'s `duration` field.
359#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
360#[serde(rename_all = "snake_case")]
361pub enum CouponDuration {
362    Forever,
363    Once,
364    Repeating,
365}
366
367impl CouponDuration {
368    pub fn as_str(self) -> &'static str {
369        match self {
370            CouponDuration::Forever => "forever",
371            CouponDuration::Once => "once",
372            CouponDuration::Repeating => "repeating",
373        }
374    }
375}
376
377impl AsRef<str> for CouponDuration {
378    fn as_ref(&self) -> &str {
379        self.as_str()
380    }
381}
382
383impl std::fmt::Display for CouponDuration {
384    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
385        self.as_str().fmt(f)
386    }
387}
388impl std::default::Default for CouponDuration {
389    fn default() -> Self {
390        Self::Forever
391    }
392}