stripe_shared/
credit_note.rs

1/// Issue a credit note to adjust an invoice's amount after the invoice is finalized.
2///
3/// Related guide: [Credit notes](https://stripe.com/docs/billing/invoices/credit-notes)
4///
5/// For more details see <<https://stripe.com/docs/api/credit_notes/object>>.
6#[derive(Clone, Debug)]
7#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
8pub struct CreditNote {
9    /// The integer amount in cents (or local equivalent) representing the total amount of the credit note, including tax.
10    pub amount: i64,
11    /// This is the sum of all the shipping amounts.
12    pub amount_shipping: i64,
13    /// Time at which the object was created. Measured in seconds since the Unix epoch.
14    pub created: stripe_types::Timestamp,
15    /// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
16    /// Must be a [supported currency](https://stripe.com/docs/currencies).
17    pub currency: stripe_types::Currency,
18    /// ID of the customer.
19    pub customer: stripe_types::Expandable<stripe_shared::Customer>,
20    /// Customer balance transaction related to this credit note.
21    pub customer_balance_transaction:
22        Option<stripe_types::Expandable<stripe_shared::CustomerBalanceTransaction>>,
23    /// The integer amount in cents (or local equivalent) representing the total amount of discount that was credited.
24    pub discount_amount: i64,
25    /// The aggregate amounts calculated per discount for all line items.
26    pub discount_amounts: Vec<stripe_shared::DiscountsResourceDiscountAmount>,
27    /// The date when this credit note is in effect.
28    /// Same as `created` unless overwritten.
29    /// When defined, this value replaces the system-generated 'Date of issue' printed on the credit note PDF.
30    pub effective_at: Option<stripe_types::Timestamp>,
31    /// Unique identifier for the object.
32    pub id: stripe_shared::CreditNoteId,
33    /// ID of the invoice.
34    pub invoice: stripe_types::Expandable<stripe_shared::Invoice>,
35    /// Line items that make up the credit note
36    pub lines: stripe_types::List<stripe_shared::CreditNoteLineItem>,
37    /// Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode.
38    pub livemode: bool,
39    /// Customer-facing text that appears on the credit note PDF.
40    pub memo: Option<String>,
41    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
42    /// This can be useful for storing additional information about the object in a structured format.
43    pub metadata: Option<std::collections::HashMap<String, String>>,
44    /// A unique number that identifies this particular credit note and appears on the PDF of the credit note and its associated invoice.
45    pub number: String,
46    /// Amount that was credited outside of Stripe.
47    pub out_of_band_amount: Option<i64>,
48    /// The link to download the PDF of the credit note.
49    pub pdf: String,
50    /// The pretax credit amounts (ex: discount, credit grants, etc) for all line items.
51    pub pretax_credit_amounts: Vec<stripe_shared::CreditNotesPretaxCreditAmount>,
52    /// Reason for issuing this credit note, one of `duplicate`, `fraudulent`, `order_change`, or `product_unsatisfactory`.
53    pub reason: Option<stripe_shared::CreditNoteReason>,
54    /// Refunds related to this credit note.
55    pub refunds: Vec<stripe_shared::CreditNoteRefund>,
56    /// The details of the cost of shipping, including the ShippingRate applied to the invoice.
57    pub shipping_cost: Option<stripe_shared::InvoicesResourceShippingCost>,
58    /// Status of this credit note, one of `issued` or `void`.
59    /// Learn more about [voiding credit notes](https://stripe.com/docs/billing/invoices/credit-notes#voiding).
60    pub status: CreditNoteStatus,
61    /// The integer amount in cents (or local equivalent) representing the amount of the credit note, excluding exclusive tax and invoice level discounts.
62    pub subtotal: i64,
63    /// The integer amount in cents (or local equivalent) representing the amount of the credit note, excluding all tax and invoice level discounts.
64    pub subtotal_excluding_tax: Option<i64>,
65    /// The integer amount in cents (or local equivalent) representing the total amount of the credit note, including tax and all discount.
66    pub total: i64,
67    /// The integer amount in cents (or local equivalent) representing the total amount of the credit note, excluding tax, but including discounts.
68    pub total_excluding_tax: Option<i64>,
69    /// The aggregate tax information for all line items.
70    pub total_taxes: Option<Vec<stripe_shared::BillingBillResourceInvoicingTaxesTax>>,
71    /// Type of this credit note, one of `pre_payment` or `post_payment`.
72    /// A `pre_payment` credit note means it was issued when the invoice was open.
73    /// A `post_payment` credit note means it was issued when the invoice was paid.
74    #[cfg_attr(feature = "deserialize", serde(rename = "type"))]
75    pub type_: CreditNoteType,
76    /// The time that the credit note was voided.
77    pub voided_at: Option<stripe_types::Timestamp>,
78}
79#[doc(hidden)]
80pub struct CreditNoteBuilder {
81    amount: Option<i64>,
82    amount_shipping: Option<i64>,
83    created: Option<stripe_types::Timestamp>,
84    currency: Option<stripe_types::Currency>,
85    customer: Option<stripe_types::Expandable<stripe_shared::Customer>>,
86    customer_balance_transaction:
87        Option<Option<stripe_types::Expandable<stripe_shared::CustomerBalanceTransaction>>>,
88    discount_amount: Option<i64>,
89    discount_amounts: Option<Vec<stripe_shared::DiscountsResourceDiscountAmount>>,
90    effective_at: Option<Option<stripe_types::Timestamp>>,
91    id: Option<stripe_shared::CreditNoteId>,
92    invoice: Option<stripe_types::Expandable<stripe_shared::Invoice>>,
93    lines: Option<stripe_types::List<stripe_shared::CreditNoteLineItem>>,
94    livemode: Option<bool>,
95    memo: Option<Option<String>>,
96    metadata: Option<Option<std::collections::HashMap<String, String>>>,
97    number: Option<String>,
98    out_of_band_amount: Option<Option<i64>>,
99    pdf: Option<String>,
100    pretax_credit_amounts: Option<Vec<stripe_shared::CreditNotesPretaxCreditAmount>>,
101    reason: Option<Option<stripe_shared::CreditNoteReason>>,
102    refunds: Option<Vec<stripe_shared::CreditNoteRefund>>,
103    shipping_cost: Option<Option<stripe_shared::InvoicesResourceShippingCost>>,
104    status: Option<CreditNoteStatus>,
105    subtotal: Option<i64>,
106    subtotal_excluding_tax: Option<Option<i64>>,
107    total: Option<i64>,
108    total_excluding_tax: Option<Option<i64>>,
109    total_taxes: Option<Option<Vec<stripe_shared::BillingBillResourceInvoicingTaxesTax>>>,
110    type_: Option<CreditNoteType>,
111    voided_at: Option<Option<stripe_types::Timestamp>>,
112}
113
114#[allow(
115    unused_variables,
116    irrefutable_let_patterns,
117    clippy::let_unit_value,
118    clippy::match_single_binding,
119    clippy::single_match
120)]
121const _: () = {
122    use miniserde::de::{Map, Visitor};
123    use miniserde::json::Value;
124    use miniserde::{make_place, Deserialize, Result};
125    use stripe_types::miniserde_helpers::FromValueOpt;
126    use stripe_types::{MapBuilder, ObjectDeser};
127
128    make_place!(Place);
129
130    impl Deserialize for CreditNote {
131        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
132            Place::new(out)
133        }
134    }
135
136    struct Builder<'a> {
137        out: &'a mut Option<CreditNote>,
138        builder: CreditNoteBuilder,
139    }
140
141    impl Visitor for Place<CreditNote> {
142        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
143            Ok(Box::new(Builder {
144                out: &mut self.out,
145                builder: CreditNoteBuilder::deser_default(),
146            }))
147        }
148    }
149
150    impl MapBuilder for CreditNoteBuilder {
151        type Out = CreditNote;
152        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
153            Ok(match k {
154                "amount" => Deserialize::begin(&mut self.amount),
155                "amount_shipping" => Deserialize::begin(&mut self.amount_shipping),
156                "created" => Deserialize::begin(&mut self.created),
157                "currency" => Deserialize::begin(&mut self.currency),
158                "customer" => Deserialize::begin(&mut self.customer),
159                "customer_balance_transaction" => {
160                    Deserialize::begin(&mut self.customer_balance_transaction)
161                }
162                "discount_amount" => Deserialize::begin(&mut self.discount_amount),
163                "discount_amounts" => Deserialize::begin(&mut self.discount_amounts),
164                "effective_at" => Deserialize::begin(&mut self.effective_at),
165                "id" => Deserialize::begin(&mut self.id),
166                "invoice" => Deserialize::begin(&mut self.invoice),
167                "lines" => Deserialize::begin(&mut self.lines),
168                "livemode" => Deserialize::begin(&mut self.livemode),
169                "memo" => Deserialize::begin(&mut self.memo),
170                "metadata" => Deserialize::begin(&mut self.metadata),
171                "number" => Deserialize::begin(&mut self.number),
172                "out_of_band_amount" => Deserialize::begin(&mut self.out_of_band_amount),
173                "pdf" => Deserialize::begin(&mut self.pdf),
174                "pretax_credit_amounts" => Deserialize::begin(&mut self.pretax_credit_amounts),
175                "reason" => Deserialize::begin(&mut self.reason),
176                "refunds" => Deserialize::begin(&mut self.refunds),
177                "shipping_cost" => Deserialize::begin(&mut self.shipping_cost),
178                "status" => Deserialize::begin(&mut self.status),
179                "subtotal" => Deserialize::begin(&mut self.subtotal),
180                "subtotal_excluding_tax" => Deserialize::begin(&mut self.subtotal_excluding_tax),
181                "total" => Deserialize::begin(&mut self.total),
182                "total_excluding_tax" => Deserialize::begin(&mut self.total_excluding_tax),
183                "total_taxes" => Deserialize::begin(&mut self.total_taxes),
184                "type" => Deserialize::begin(&mut self.type_),
185                "voided_at" => Deserialize::begin(&mut self.voided_at),
186
187                _ => <dyn Visitor>::ignore(),
188            })
189        }
190
191        fn deser_default() -> Self {
192            Self {
193                amount: Deserialize::default(),
194                amount_shipping: Deserialize::default(),
195                created: Deserialize::default(),
196                currency: Deserialize::default(),
197                customer: Deserialize::default(),
198                customer_balance_transaction: Deserialize::default(),
199                discount_amount: Deserialize::default(),
200                discount_amounts: Deserialize::default(),
201                effective_at: Deserialize::default(),
202                id: Deserialize::default(),
203                invoice: Deserialize::default(),
204                lines: Deserialize::default(),
205                livemode: Deserialize::default(),
206                memo: Deserialize::default(),
207                metadata: Deserialize::default(),
208                number: Deserialize::default(),
209                out_of_band_amount: Deserialize::default(),
210                pdf: Deserialize::default(),
211                pretax_credit_amounts: Deserialize::default(),
212                reason: Deserialize::default(),
213                refunds: Deserialize::default(),
214                shipping_cost: Deserialize::default(),
215                status: Deserialize::default(),
216                subtotal: Deserialize::default(),
217                subtotal_excluding_tax: Deserialize::default(),
218                total: Deserialize::default(),
219                total_excluding_tax: Deserialize::default(),
220                total_taxes: Deserialize::default(),
221                type_: Deserialize::default(),
222                voided_at: Deserialize::default(),
223            }
224        }
225
226        fn take_out(&mut self) -> Option<Self::Out> {
227            let (
228                Some(amount),
229                Some(amount_shipping),
230                Some(created),
231                Some(currency),
232                Some(customer),
233                Some(customer_balance_transaction),
234                Some(discount_amount),
235                Some(discount_amounts),
236                Some(effective_at),
237                Some(id),
238                Some(invoice),
239                Some(lines),
240                Some(livemode),
241                Some(memo),
242                Some(metadata),
243                Some(number),
244                Some(out_of_band_amount),
245                Some(pdf),
246                Some(pretax_credit_amounts),
247                Some(reason),
248                Some(refunds),
249                Some(shipping_cost),
250                Some(status),
251                Some(subtotal),
252                Some(subtotal_excluding_tax),
253                Some(total),
254                Some(total_excluding_tax),
255                Some(total_taxes),
256                Some(type_),
257                Some(voided_at),
258            ) = (
259                self.amount,
260                self.amount_shipping,
261                self.created,
262                self.currency,
263                self.customer.take(),
264                self.customer_balance_transaction.take(),
265                self.discount_amount,
266                self.discount_amounts.take(),
267                self.effective_at,
268                self.id.take(),
269                self.invoice.take(),
270                self.lines.take(),
271                self.livemode,
272                self.memo.take(),
273                self.metadata.take(),
274                self.number.take(),
275                self.out_of_band_amount,
276                self.pdf.take(),
277                self.pretax_credit_amounts.take(),
278                self.reason,
279                self.refunds.take(),
280                self.shipping_cost.take(),
281                self.status,
282                self.subtotal,
283                self.subtotal_excluding_tax,
284                self.total,
285                self.total_excluding_tax,
286                self.total_taxes.take(),
287                self.type_,
288                self.voided_at,
289            )
290            else {
291                return None;
292            };
293            Some(Self::Out {
294                amount,
295                amount_shipping,
296                created,
297                currency,
298                customer,
299                customer_balance_transaction,
300                discount_amount,
301                discount_amounts,
302                effective_at,
303                id,
304                invoice,
305                lines,
306                livemode,
307                memo,
308                metadata,
309                number,
310                out_of_band_amount,
311                pdf,
312                pretax_credit_amounts,
313                reason,
314                refunds,
315                shipping_cost,
316                status,
317                subtotal,
318                subtotal_excluding_tax,
319                total,
320                total_excluding_tax,
321                total_taxes,
322                type_,
323                voided_at,
324            })
325        }
326    }
327
328    impl<'a> Map for Builder<'a> {
329        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
330            self.builder.key(k)
331        }
332
333        fn finish(&mut self) -> Result<()> {
334            *self.out = self.builder.take_out();
335            Ok(())
336        }
337    }
338
339    impl ObjectDeser for CreditNote {
340        type Builder = CreditNoteBuilder;
341    }
342
343    impl FromValueOpt for CreditNote {
344        fn from_value(v: Value) -> Option<Self> {
345            let Value::Object(obj) = v else {
346                return None;
347            };
348            let mut b = CreditNoteBuilder::deser_default();
349            for (k, v) in obj {
350                match k.as_str() {
351                    "amount" => b.amount = FromValueOpt::from_value(v),
352                    "amount_shipping" => b.amount_shipping = FromValueOpt::from_value(v),
353                    "created" => b.created = FromValueOpt::from_value(v),
354                    "currency" => b.currency = FromValueOpt::from_value(v),
355                    "customer" => b.customer = FromValueOpt::from_value(v),
356                    "customer_balance_transaction" => {
357                        b.customer_balance_transaction = FromValueOpt::from_value(v)
358                    }
359                    "discount_amount" => b.discount_amount = FromValueOpt::from_value(v),
360                    "discount_amounts" => b.discount_amounts = FromValueOpt::from_value(v),
361                    "effective_at" => b.effective_at = FromValueOpt::from_value(v),
362                    "id" => b.id = FromValueOpt::from_value(v),
363                    "invoice" => b.invoice = FromValueOpt::from_value(v),
364                    "lines" => b.lines = FromValueOpt::from_value(v),
365                    "livemode" => b.livemode = FromValueOpt::from_value(v),
366                    "memo" => b.memo = FromValueOpt::from_value(v),
367                    "metadata" => b.metadata = FromValueOpt::from_value(v),
368                    "number" => b.number = FromValueOpt::from_value(v),
369                    "out_of_band_amount" => b.out_of_band_amount = FromValueOpt::from_value(v),
370                    "pdf" => b.pdf = FromValueOpt::from_value(v),
371                    "pretax_credit_amounts" => {
372                        b.pretax_credit_amounts = FromValueOpt::from_value(v)
373                    }
374                    "reason" => b.reason = FromValueOpt::from_value(v),
375                    "refunds" => b.refunds = FromValueOpt::from_value(v),
376                    "shipping_cost" => b.shipping_cost = FromValueOpt::from_value(v),
377                    "status" => b.status = FromValueOpt::from_value(v),
378                    "subtotal" => b.subtotal = FromValueOpt::from_value(v),
379                    "subtotal_excluding_tax" => {
380                        b.subtotal_excluding_tax = FromValueOpt::from_value(v)
381                    }
382                    "total" => b.total = FromValueOpt::from_value(v),
383                    "total_excluding_tax" => b.total_excluding_tax = FromValueOpt::from_value(v),
384                    "total_taxes" => b.total_taxes = FromValueOpt::from_value(v),
385                    "type" => b.type_ = FromValueOpt::from_value(v),
386                    "voided_at" => b.voided_at = FromValueOpt::from_value(v),
387
388                    _ => {}
389                }
390            }
391            b.take_out()
392        }
393    }
394};
395#[cfg(feature = "serialize")]
396impl serde::Serialize for CreditNote {
397    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
398        use serde::ser::SerializeStruct;
399        let mut s = s.serialize_struct("CreditNote", 31)?;
400        s.serialize_field("amount", &self.amount)?;
401        s.serialize_field("amount_shipping", &self.amount_shipping)?;
402        s.serialize_field("created", &self.created)?;
403        s.serialize_field("currency", &self.currency)?;
404        s.serialize_field("customer", &self.customer)?;
405        s.serialize_field("customer_balance_transaction", &self.customer_balance_transaction)?;
406        s.serialize_field("discount_amount", &self.discount_amount)?;
407        s.serialize_field("discount_amounts", &self.discount_amounts)?;
408        s.serialize_field("effective_at", &self.effective_at)?;
409        s.serialize_field("id", &self.id)?;
410        s.serialize_field("invoice", &self.invoice)?;
411        s.serialize_field("lines", &self.lines)?;
412        s.serialize_field("livemode", &self.livemode)?;
413        s.serialize_field("memo", &self.memo)?;
414        s.serialize_field("metadata", &self.metadata)?;
415        s.serialize_field("number", &self.number)?;
416        s.serialize_field("out_of_band_amount", &self.out_of_band_amount)?;
417        s.serialize_field("pdf", &self.pdf)?;
418        s.serialize_field("pretax_credit_amounts", &self.pretax_credit_amounts)?;
419        s.serialize_field("reason", &self.reason)?;
420        s.serialize_field("refunds", &self.refunds)?;
421        s.serialize_field("shipping_cost", &self.shipping_cost)?;
422        s.serialize_field("status", &self.status)?;
423        s.serialize_field("subtotal", &self.subtotal)?;
424        s.serialize_field("subtotal_excluding_tax", &self.subtotal_excluding_tax)?;
425        s.serialize_field("total", &self.total)?;
426        s.serialize_field("total_excluding_tax", &self.total_excluding_tax)?;
427        s.serialize_field("total_taxes", &self.total_taxes)?;
428        s.serialize_field("type", &self.type_)?;
429        s.serialize_field("voided_at", &self.voided_at)?;
430
431        s.serialize_field("object", "credit_note")?;
432        s.end()
433    }
434}
435/// Status of this credit note, one of `issued` or `void`.
436/// Learn more about [voiding credit notes](https://stripe.com/docs/billing/invoices/credit-notes#voiding).
437#[derive(Copy, Clone, Eq, PartialEq)]
438pub enum CreditNoteStatus {
439    Issued,
440    Void,
441}
442impl CreditNoteStatus {
443    pub fn as_str(self) -> &'static str {
444        use CreditNoteStatus::*;
445        match self {
446            Issued => "issued",
447            Void => "void",
448        }
449    }
450}
451
452impl std::str::FromStr for CreditNoteStatus {
453    type Err = stripe_types::StripeParseError;
454    fn from_str(s: &str) -> Result<Self, Self::Err> {
455        use CreditNoteStatus::*;
456        match s {
457            "issued" => Ok(Issued),
458            "void" => Ok(Void),
459            _ => Err(stripe_types::StripeParseError),
460        }
461    }
462}
463impl std::fmt::Display for CreditNoteStatus {
464    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
465        f.write_str(self.as_str())
466    }
467}
468
469impl std::fmt::Debug for CreditNoteStatus {
470    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
471        f.write_str(self.as_str())
472    }
473}
474#[cfg(feature = "serialize")]
475impl serde::Serialize for CreditNoteStatus {
476    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
477    where
478        S: serde::Serializer,
479    {
480        serializer.serialize_str(self.as_str())
481    }
482}
483impl miniserde::Deserialize for CreditNoteStatus {
484    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
485        crate::Place::new(out)
486    }
487}
488
489impl miniserde::de::Visitor for crate::Place<CreditNoteStatus> {
490    fn string(&mut self, s: &str) -> miniserde::Result<()> {
491        use std::str::FromStr;
492        self.out = Some(CreditNoteStatus::from_str(s).map_err(|_| miniserde::Error)?);
493        Ok(())
494    }
495}
496
497stripe_types::impl_from_val_with_from_str!(CreditNoteStatus);
498#[cfg(feature = "deserialize")]
499impl<'de> serde::Deserialize<'de> for CreditNoteStatus {
500    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
501        use std::str::FromStr;
502        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
503        Self::from_str(&s)
504            .map_err(|_| serde::de::Error::custom("Unknown value for CreditNoteStatus"))
505    }
506}
507/// Type of this credit note, one of `pre_payment` or `post_payment`.
508/// A `pre_payment` credit note means it was issued when the invoice was open.
509/// A `post_payment` credit note means it was issued when the invoice was paid.
510#[derive(Copy, Clone, Eq, PartialEq)]
511pub enum CreditNoteType {
512    PostPayment,
513    PrePayment,
514}
515impl CreditNoteType {
516    pub fn as_str(self) -> &'static str {
517        use CreditNoteType::*;
518        match self {
519            PostPayment => "post_payment",
520            PrePayment => "pre_payment",
521        }
522    }
523}
524
525impl std::str::FromStr for CreditNoteType {
526    type Err = stripe_types::StripeParseError;
527    fn from_str(s: &str) -> Result<Self, Self::Err> {
528        use CreditNoteType::*;
529        match s {
530            "post_payment" => Ok(PostPayment),
531            "pre_payment" => Ok(PrePayment),
532            _ => Err(stripe_types::StripeParseError),
533        }
534    }
535}
536impl std::fmt::Display for CreditNoteType {
537    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
538        f.write_str(self.as_str())
539    }
540}
541
542impl std::fmt::Debug for CreditNoteType {
543    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
544        f.write_str(self.as_str())
545    }
546}
547#[cfg(feature = "serialize")]
548impl serde::Serialize for CreditNoteType {
549    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
550    where
551        S: serde::Serializer,
552    {
553        serializer.serialize_str(self.as_str())
554    }
555}
556impl miniserde::Deserialize for CreditNoteType {
557    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
558        crate::Place::new(out)
559    }
560}
561
562impl miniserde::de::Visitor for crate::Place<CreditNoteType> {
563    fn string(&mut self, s: &str) -> miniserde::Result<()> {
564        use std::str::FromStr;
565        self.out = Some(CreditNoteType::from_str(s).map_err(|_| miniserde::Error)?);
566        Ok(())
567    }
568}
569
570stripe_types::impl_from_val_with_from_str!(CreditNoteType);
571#[cfg(feature = "deserialize")]
572impl<'de> serde::Deserialize<'de> for CreditNoteType {
573    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
574        use std::str::FromStr;
575        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
576        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for CreditNoteType"))
577    }
578}
579impl stripe_types::Object for CreditNote {
580    type Id = stripe_shared::CreditNoteId;
581    fn id(&self) -> &Self::Id {
582        &self.id
583    }
584
585    fn into_id(self) -> Self::Id {
586        self.id
587    }
588}
589stripe_types::def_id!(CreditNoteId);
590#[derive(Copy, Clone, Eq, PartialEq)]
591pub enum CreditNoteReason {
592    Duplicate,
593    Fraudulent,
594    OrderChange,
595    ProductUnsatisfactory,
596}
597impl CreditNoteReason {
598    pub fn as_str(self) -> &'static str {
599        use CreditNoteReason::*;
600        match self {
601            Duplicate => "duplicate",
602            Fraudulent => "fraudulent",
603            OrderChange => "order_change",
604            ProductUnsatisfactory => "product_unsatisfactory",
605        }
606    }
607}
608
609impl std::str::FromStr for CreditNoteReason {
610    type Err = stripe_types::StripeParseError;
611    fn from_str(s: &str) -> Result<Self, Self::Err> {
612        use CreditNoteReason::*;
613        match s {
614            "duplicate" => Ok(Duplicate),
615            "fraudulent" => Ok(Fraudulent),
616            "order_change" => Ok(OrderChange),
617            "product_unsatisfactory" => Ok(ProductUnsatisfactory),
618            _ => Err(stripe_types::StripeParseError),
619        }
620    }
621}
622impl std::fmt::Display for CreditNoteReason {
623    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
624        f.write_str(self.as_str())
625    }
626}
627
628impl std::fmt::Debug for CreditNoteReason {
629    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
630        f.write_str(self.as_str())
631    }
632}
633impl serde::Serialize for CreditNoteReason {
634    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
635    where
636        S: serde::Serializer,
637    {
638        serializer.serialize_str(self.as_str())
639    }
640}
641impl miniserde::Deserialize for CreditNoteReason {
642    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
643        crate::Place::new(out)
644    }
645}
646
647impl miniserde::de::Visitor for crate::Place<CreditNoteReason> {
648    fn string(&mut self, s: &str) -> miniserde::Result<()> {
649        use std::str::FromStr;
650        self.out = Some(CreditNoteReason::from_str(s).map_err(|_| miniserde::Error)?);
651        Ok(())
652    }
653}
654
655stripe_types::impl_from_val_with_from_str!(CreditNoteReason);
656#[cfg(feature = "deserialize")]
657impl<'de> serde::Deserialize<'de> for CreditNoteReason {
658    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
659        use std::str::FromStr;
660        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
661        Self::from_str(&s)
662            .map_err(|_| serde::de::Error::custom("Unknown value for CreditNoteReason"))
663    }
664}