stripe/resources/generated/
refund.rs

1// ======================================
2// This file was automatically generated.
3// ======================================
4
5use crate::client::{Client, Response};
6use crate::ids::{ChargeId, CustomerId, PaymentIntentId, RefundId};
7use crate::params::{Expand, Expandable, List, Metadata, Object, Paginable, RangeQuery, Timestamp};
8use crate::resources::{BalanceTransaction, Charge, Currency, PaymentIntent, TransferReversal};
9use serde::{Deserialize, Serialize};
10
11/// The resource representing a Stripe "Refund".
12///
13/// For more details see <https://stripe.com/docs/api/refunds/object>
14#[derive(Clone, Debug, Default, Deserialize, Serialize)]
15pub struct Refund {
16    /// Unique identifier for the object.
17    pub id: RefundId,
18
19    /// Amount, in cents (or local equivalent).
20    pub amount: i64,
21
22    /// Balance transaction that describes the impact on your account balance.
23    pub balance_transaction: Option<Expandable<BalanceTransaction>>,
24
25    /// ID of the charge that's refunded.
26    pub charge: Option<Expandable<Charge>>,
27
28    /// Time at which the object was created.
29    ///
30    /// Measured in seconds since the Unix epoch.
31    pub created: Timestamp,
32
33    /// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
34    ///
35    /// Must be a [supported currency](https://stripe.com/docs/currencies).
36    pub currency: Currency,
37
38    /// An arbitrary string attached to the object.
39    ///
40    /// You can use this for displaying to users (available on non-card refunds only).
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub description: Option<String>,
43
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub destination_details: Option<RefundDestinationDetails>,
46
47    /// After the refund fails, this balance transaction describes the adjustment made on your account balance that reverses the initial balance transaction.
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub failure_balance_transaction: Option<Expandable<BalanceTransaction>>,
50
51    /// Provides the reason for the refund failure.
52    ///
53    /// Possible values are: `lost_or_stolen_card`, `expired_or_canceled_card`, `charge_for_pending_refund_disputed`, `insufficient_funds`, `declined`, `merchant_request`, or `unknown`.
54    #[serde(skip_serializing_if = "Option::is_none")]
55    pub failure_reason: Option<String>,
56
57    /// For payment methods without native refund support (for example, Konbini, PromptPay), provide an email address for the customer to receive refund instructions.
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub instructions_email: Option<String>,
60
61    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
62    ///
63    /// This can be useful for storing additional information about the object in a structured format.
64    pub metadata: Option<Metadata>,
65
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub next_action: Option<RefundNextAction>,
68
69    /// ID of the PaymentIntent that's refunded.
70    pub payment_intent: Option<Expandable<PaymentIntent>>,
71
72    /// Reason for the refund, which is either user-provided (`duplicate`, `fraudulent`, or `requested_by_customer`) or generated by Stripe internally (`expired_uncaptured_charge`).
73    pub reason: Option<RefundReason>,
74
75    /// This is the transaction number that appears on email receipts sent for this refund.
76    pub receipt_number: Option<String>,
77
78    /// The transfer reversal that's associated with the refund.
79    ///
80    /// Only present if the charge came from another Stripe account.
81    pub source_transfer_reversal: Option<Expandable<TransferReversal>>,
82
83    /// Status of the refund.
84    ///
85    /// This can be `pending`, `requires_action`, `succeeded`, `failed`, or `canceled`.
86    /// Learn more about [failed refunds](https://stripe.com/docs/refunds#failed-refunds).
87    pub status: Option<String>,
88
89    /// This refers to the transfer reversal object if the accompanying transfer reverses.
90    ///
91    /// This is only applicable if the charge was created using the destination parameter.
92    pub transfer_reversal: Option<Expandable<TransferReversal>>,
93}
94
95impl Refund {
96    /// Returns a list of all refunds you created.
97    ///
98    /// We return the refunds in sorted order, with the most recent refunds appearing first The 10 most recent refunds are always available by default on the Charge object.
99    pub fn list(client: &Client, params: &ListRefunds<'_>) -> Response<List<Refund>> {
100        client.get_query("/refunds", params)
101    }
102
103    /// When you create a new refund, you must specify a Charge or a PaymentIntent object on which to create it.
104    ///
105    /// Creating a new refund will refund a charge that has previously been created but not yet refunded.
106    /// Funds will be refunded to the credit or debit card that was originally charged.
107    ///
108    /// You can optionally refund only part of a charge.
109    /// You can do so multiple times, until the entire charge has been refunded.
110    ///
111    /// Once entirely refunded, a charge can’t be refunded again.
112    /// This method will raise an error when called on an already-refunded charge,
113    /// or when trying to refund more money than is left on a charge.
114    pub fn create(client: &Client, params: CreateRefund<'_>) -> Response<Refund> {
115        #[allow(clippy::needless_borrows_for_generic_args)]
116        client.post_form("/refunds", &params)
117    }
118
119    /// Retrieves the details of an existing refund.
120    pub fn retrieve(client: &Client, id: &RefundId, expand: &[&str]) -> Response<Refund> {
121        client.get_query(&format!("/refunds/{}", id), Expand { expand })
122    }
123
124    /// Updates the refund that you specify by setting the values of the passed parameters.
125    ///
126    /// Any parameters that you don’t provide remain unchanged.  This request only accepts `metadata` as an argument.
127    pub fn update(client: &Client, id: &RefundId, params: UpdateRefund<'_>) -> Response<Refund> {
128        #[allow(clippy::needless_borrows_for_generic_args)]
129        client.post_form(&format!("/refunds/{}", id), &params)
130    }
131}
132
133impl Object for Refund {
134    type Id = RefundId;
135    fn id(&self) -> Self::Id {
136        self.id.clone()
137    }
138    fn object(&self) -> &'static str {
139        "refund"
140    }
141}
142
143#[derive(Clone, Debug, Default, Deserialize, Serialize)]
144pub struct RefundDestinationDetails {
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub affirm: Option<DestinationDetailsUnimplemented>,
147
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub afterpay_clearpay: Option<DestinationDetailsUnimplemented>,
150
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub alipay: Option<DestinationDetailsUnimplemented>,
153
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub au_bank_transfer: Option<DestinationDetailsUnimplemented>,
156
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub blik: Option<RefundDestinationDetailsGeneric>,
159
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub br_bank_transfer: Option<RefundDestinationDetailsGeneric>,
162
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub card: Option<RefundDestinationDetailsCard>,
165
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub cashapp: Option<DestinationDetailsUnimplemented>,
168
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub customer_cash_balance: Option<DestinationDetailsUnimplemented>,
171
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub eps: Option<DestinationDetailsUnimplemented>,
174
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub eu_bank_transfer: Option<RefundDestinationDetailsGeneric>,
177
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub gb_bank_transfer: Option<RefundDestinationDetailsGeneric>,
180
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub giropay: Option<DestinationDetailsUnimplemented>,
183
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub grabpay: Option<DestinationDetailsUnimplemented>,
186
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub jp_bank_transfer: Option<RefundDestinationDetailsGeneric>,
189
190    #[serde(skip_serializing_if = "Option::is_none")]
191    pub klarna: Option<DestinationDetailsUnimplemented>,
192
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub mx_bank_transfer: Option<RefundDestinationDetailsGeneric>,
195
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub p24: Option<RefundDestinationDetailsGeneric>,
198
199    #[serde(skip_serializing_if = "Option::is_none")]
200    pub paynow: Option<DestinationDetailsUnimplemented>,
201
202    #[serde(skip_serializing_if = "Option::is_none")]
203    pub paypal: Option<DestinationDetailsUnimplemented>,
204
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub pix: Option<DestinationDetailsUnimplemented>,
207
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub revolut: Option<DestinationDetailsUnimplemented>,
210
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub sofort: Option<DestinationDetailsUnimplemented>,
213
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub swish: Option<RefundDestinationDetailsGeneric>,
216
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub th_bank_transfer: Option<RefundDestinationDetailsGeneric>,
219
220    /// The type of transaction-specific details of the payment method used in the refund (e.g., `card`).
221    ///
222    /// An additional hash is included on `destination_details` with a name matching this value.
223    /// It contains information specific to the refund transaction.
224    #[serde(rename = "type")]
225    pub type_: String,
226
227    #[serde(skip_serializing_if = "Option::is_none")]
228    pub us_bank_transfer: Option<RefundDestinationDetailsGeneric>,
229
230    #[serde(skip_serializing_if = "Option::is_none")]
231    pub wechat_pay: Option<DestinationDetailsUnimplemented>,
232
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub zip: Option<DestinationDetailsUnimplemented>,
235}
236
237#[derive(Clone, Debug, Default, Deserialize, Serialize)]
238pub struct DestinationDetailsUnimplemented {}
239
240#[derive(Clone, Debug, Default, Deserialize, Serialize)]
241pub struct RefundDestinationDetailsCard {
242    /// Value of the reference number assigned to the refund.
243    #[serde(skip_serializing_if = "Option::is_none")]
244    pub reference: Option<String>,
245
246    /// Status of the reference number on the refund.
247    ///
248    /// This can be `pending`, `available` or `unavailable`.
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub reference_status: Option<String>,
251
252    /// Type of the reference number assigned to the refund.
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub reference_type: Option<String>,
255
256    /// The type of refund.
257    ///
258    /// This can be `refund`, `reversal`, or `pending`.
259    #[serde(rename = "type")]
260    pub type_: RefundDestinationDetailsCardType,
261}
262
263#[derive(Clone, Debug, Default, Deserialize, Serialize)]
264pub struct RefundDestinationDetailsGeneric {
265    /// The reference assigned to the refund.
266    pub reference: Option<String>,
267
268    /// Status of the reference on the refund.
269    ///
270    /// This can be `pending`, `available` or `unavailable`.
271    pub reference_status: Option<String>,
272}
273
274#[derive(Clone, Debug, Default, Deserialize, Serialize)]
275pub struct RefundNextAction {
276    /// Contains the refund details.
277    pub display_details: Option<RefundNextActionDisplayDetails>,
278
279    /// Type of the next action to perform.
280    #[serde(rename = "type")]
281    pub type_: String,
282}
283
284#[derive(Clone, Debug, Default, Deserialize, Serialize)]
285pub struct RefundNextActionDisplayDetails {
286    pub email_sent: EmailSent,
287
288    /// The expiry timestamp.
289    pub expires_at: Timestamp,
290}
291
292#[derive(Clone, Debug, Default, Deserialize, Serialize)]
293pub struct EmailSent {
294    /// The timestamp when the email was sent.
295    pub email_sent_at: Timestamp,
296
297    /// The recipient's email address.
298    pub email_sent_to: String,
299}
300
301/// The parameters for `Refund::create`.
302#[derive(Clone, Debug, Serialize, Default)]
303pub struct CreateRefund<'a> {
304    #[serde(skip_serializing_if = "Option::is_none")]
305    pub amount: Option<i64>,
306
307    /// The identifier of the charge to refund.
308    #[serde(skip_serializing_if = "Option::is_none")]
309    pub charge: Option<ChargeId>,
310
311    /// Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase.
312    ///
313    /// Must be a [supported currency](https://stripe.com/docs/currencies).
314    #[serde(skip_serializing_if = "Option::is_none")]
315    pub currency: Option<Currency>,
316
317    /// Customer whose customer balance to refund from.
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub customer: Option<CustomerId>,
320
321    /// Specifies which fields in the response should be expanded.
322    #[serde(skip_serializing_if = "Expand::is_empty")]
323    pub expand: &'a [&'a str],
324
325    /// For payment methods without native refund support (e.g., Konbini, PromptPay), use this email from the customer to receive refund instructions.
326    #[serde(skip_serializing_if = "Option::is_none")]
327    pub instructions_email: Option<&'a str>,
328
329    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
330    ///
331    /// This can be useful for storing additional information about the object in a structured format.
332    /// Individual keys can be unset by posting an empty value to them.
333    /// All keys can be unset by posting an empty value to `metadata`.
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub metadata: Option<Metadata>,
336
337    /// Origin of the refund.
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub origin: Option<RefundOrigin>,
340
341    /// The identifier of the PaymentIntent to refund.
342    #[serde(skip_serializing_if = "Option::is_none")]
343    pub payment_intent: Option<PaymentIntentId>,
344
345    /// String indicating the reason for the refund.
346    ///
347    /// If set, possible values are `duplicate`, `fraudulent`, and `requested_by_customer`.
348    /// If you believe the charge to be fraudulent, specifying `fraudulent` as the reason will add the associated card and email to your [block lists](https://stripe.com/docs/radar/lists), and will also help us improve our fraud detection algorithms.
349    #[serde(skip_serializing_if = "Option::is_none")]
350    pub reason: Option<RefundReasonFilter>,
351
352    /// Boolean indicating whether the application fee should be refunded when refunding this charge.
353    ///
354    /// If a full charge refund is given, the full application fee will be refunded.
355    /// Otherwise, the application fee will be refunded in an amount proportional to the amount of the charge refunded.
356    /// An application fee can be refunded only by the application that created the charge.
357    #[serde(skip_serializing_if = "Option::is_none")]
358    pub refund_application_fee: Option<bool>,
359
360    /// Boolean indicating whether the transfer should be reversed when refunding this charge.
361    ///
362    /// The transfer will be reversed proportionally to the amount being refunded (either the entire or partial amount).  A transfer can be reversed only by the application that created the charge.
363    #[serde(skip_serializing_if = "Option::is_none")]
364    pub reverse_transfer: Option<bool>,
365}
366
367impl<'a> CreateRefund<'a> {
368    pub fn new() -> Self {
369        CreateRefund {
370            amount: Default::default(),
371            charge: Default::default(),
372            currency: Default::default(),
373            customer: Default::default(),
374            expand: Default::default(),
375            instructions_email: Default::default(),
376            metadata: Default::default(),
377            origin: Default::default(),
378            payment_intent: Default::default(),
379            reason: Default::default(),
380            refund_application_fee: Default::default(),
381            reverse_transfer: Default::default(),
382        }
383    }
384}
385
386/// The parameters for `Refund::list`.
387#[derive(Clone, Debug, Serialize, Default)]
388pub struct ListRefunds<'a> {
389    /// Only return refunds for the charge specified by this charge ID.
390    #[serde(skip_serializing_if = "Option::is_none")]
391    pub charge: Option<ChargeId>,
392
393    #[serde(skip_serializing_if = "Option::is_none")]
394    pub created: Option<RangeQuery<Timestamp>>,
395
396    /// A cursor for use in pagination.
397    ///
398    /// `ending_before` is an object ID that defines your place in the list.
399    /// 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.
400    #[serde(skip_serializing_if = "Option::is_none")]
401    pub ending_before: Option<RefundId>,
402
403    /// Specifies which fields in the response should be expanded.
404    #[serde(skip_serializing_if = "Expand::is_empty")]
405    pub expand: &'a [&'a str],
406
407    /// A limit on the number of objects to be returned.
408    ///
409    /// Limit can range between 1 and 100, and the default is 10.
410    #[serde(skip_serializing_if = "Option::is_none")]
411    pub limit: Option<u64>,
412
413    /// Only return refunds for the PaymentIntent specified by this ID.
414    #[serde(skip_serializing_if = "Option::is_none")]
415    pub payment_intent: Option<PaymentIntentId>,
416
417    /// A cursor for use in pagination.
418    ///
419    /// `starting_after` is an object ID that defines your place in the list.
420    /// 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.
421    #[serde(skip_serializing_if = "Option::is_none")]
422    pub starting_after: Option<RefundId>,
423}
424
425impl<'a> ListRefunds<'a> {
426    pub fn new() -> Self {
427        ListRefunds {
428            charge: Default::default(),
429            created: Default::default(),
430            ending_before: Default::default(),
431            expand: Default::default(),
432            limit: Default::default(),
433            payment_intent: Default::default(),
434            starting_after: Default::default(),
435        }
436    }
437}
438impl Paginable for ListRefunds<'_> {
439    type O = Refund;
440    fn set_last(&mut self, item: Self::O) {
441        self.starting_after = Some(item.id());
442    }
443}
444/// The parameters for `Refund::update`.
445#[derive(Clone, Debug, Serialize, Default)]
446pub struct UpdateRefund<'a> {
447    /// Specifies which fields in the response should be expanded.
448    #[serde(skip_serializing_if = "Expand::is_empty")]
449    pub expand: &'a [&'a str],
450
451    /// Set of [key-value pairs](https://stripe.com/docs/api/metadata) that you can attach to an object.
452    ///
453    /// This can be useful for storing additional information about the object in a structured format.
454    /// Individual keys can be unset by posting an empty value to them.
455    /// All keys can be unset by posting an empty value to `metadata`.
456    #[serde(skip_serializing_if = "Option::is_none")]
457    pub metadata: Option<Metadata>,
458}
459
460impl<'a> UpdateRefund<'a> {
461    pub fn new() -> Self {
462        UpdateRefund { expand: Default::default(), metadata: Default::default() }
463    }
464}
465
466/// An enum representing the possible values of an `RefundDestinationDetailsCard`'s `type` field.
467#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
468#[serde(rename_all = "snake_case")]
469pub enum RefundDestinationDetailsCardType {
470    Pending,
471    Refund,
472    Reversal,
473}
474
475impl RefundDestinationDetailsCardType {
476    pub fn as_str(self) -> &'static str {
477        match self {
478            RefundDestinationDetailsCardType::Pending => "pending",
479            RefundDestinationDetailsCardType::Refund => "refund",
480            RefundDestinationDetailsCardType::Reversal => "reversal",
481        }
482    }
483}
484
485impl AsRef<str> for RefundDestinationDetailsCardType {
486    fn as_ref(&self) -> &str {
487        self.as_str()
488    }
489}
490
491impl std::fmt::Display for RefundDestinationDetailsCardType {
492    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
493        self.as_str().fmt(f)
494    }
495}
496impl std::default::Default for RefundDestinationDetailsCardType {
497    fn default() -> Self {
498        Self::Pending
499    }
500}
501
502/// An enum representing the possible values of an `CreateRefund`'s `origin` field.
503#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
504#[serde(rename_all = "snake_case")]
505pub enum RefundOrigin {
506    CustomerBalance,
507}
508
509impl RefundOrigin {
510    pub fn as_str(self) -> &'static str {
511        match self {
512            RefundOrigin::CustomerBalance => "customer_balance",
513        }
514    }
515}
516
517impl AsRef<str> for RefundOrigin {
518    fn as_ref(&self) -> &str {
519        self.as_str()
520    }
521}
522
523impl std::fmt::Display for RefundOrigin {
524    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
525        self.as_str().fmt(f)
526    }
527}
528impl std::default::Default for RefundOrigin {
529    fn default() -> Self {
530        Self::CustomerBalance
531    }
532}
533
534/// An enum representing the possible values of an `Refund`'s `reason` field.
535#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
536#[serde(rename_all = "snake_case")]
537pub enum RefundReason {
538    Duplicate,
539    ExpiredUncapturedCharge,
540    Fraudulent,
541    RequestedByCustomer,
542}
543
544impl RefundReason {
545    pub fn as_str(self) -> &'static str {
546        match self {
547            RefundReason::Duplicate => "duplicate",
548            RefundReason::ExpiredUncapturedCharge => "expired_uncaptured_charge",
549            RefundReason::Fraudulent => "fraudulent",
550            RefundReason::RequestedByCustomer => "requested_by_customer",
551        }
552    }
553}
554
555impl AsRef<str> for RefundReason {
556    fn as_ref(&self) -> &str {
557        self.as_str()
558    }
559}
560
561impl std::fmt::Display for RefundReason {
562    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
563        self.as_str().fmt(f)
564    }
565}
566impl std::default::Default for RefundReason {
567    fn default() -> Self {
568        Self::Duplicate
569    }
570}
571
572/// An enum representing the possible values of an `CreateRefund`'s `reason` field.
573#[derive(Copy, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
574#[serde(rename_all = "snake_case")]
575pub enum RefundReasonFilter {
576    Duplicate,
577    Fraudulent,
578    RequestedByCustomer,
579}
580
581impl RefundReasonFilter {
582    pub fn as_str(self) -> &'static str {
583        match self {
584            RefundReasonFilter::Duplicate => "duplicate",
585            RefundReasonFilter::Fraudulent => "fraudulent",
586            RefundReasonFilter::RequestedByCustomer => "requested_by_customer",
587        }
588    }
589}
590
591impl AsRef<str> for RefundReasonFilter {
592    fn as_ref(&self) -> &str {
593        self.as_str()
594    }
595}
596
597impl std::fmt::Display for RefundReasonFilter {
598    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
599        self.as_str().fmt(f)
600    }
601}
602impl std::default::Default for RefundReasonFilter {
603    fn default() -> Self {
604        Self::Duplicate
605    }
606}