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", ¶ms)
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), ¶ms)
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}