Skip to main content

stripe_shared/
bank_account.rs

1/// These bank accounts are payment methods on `Customer` objects.
2///
3/// On the other hand [External Accounts](/api#external_accounts) are transfer
4/// destinations on `Account` objects for connected accounts.
5/// They can be bank accounts or debit cards as well, and are documented in the links above.
6///
7/// Related guide: [Bank debits and transfers](/payments/bank-debits-transfers)
8#[derive(Clone)]
9#[cfg_attr(not(feature = "redact-generated-debug"), derive(Debug))]
10#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
11pub struct BankAccount {
12    /// The account this bank account belongs to.
13    /// Only applicable on Accounts (not customers or recipients) This property is only available when returned as an [External Account](/api/external_account_bank_accounts/object) where [controller.is_controller](/api/accounts/object#account_object-controller-is_controller) is `true`.
14    pub account: Option<stripe_types::Expandable<stripe_shared::Account>>,
15    /// The name of the person or business that owns the bank account.
16    pub account_holder_name: Option<String>,
17    /// The type of entity that holds the account. This can be either `individual` or `company`.
18    pub account_holder_type: Option<String>,
19    /// The bank account type.
20    /// This can only be `checking` or `savings` in most countries.
21    /// In Japan, this can only be `futsu` or `toza`.
22    pub account_type: Option<String>,
23    /// A set of available payout methods for this bank account.
24    /// Only values from this set should be passed as the `method` when creating a payout.
25    pub available_payout_methods: Option<Vec<BankAccountAvailablePayoutMethods>>,
26    /// Name of the bank associated with the routing number (e.g., `WELLS FARGO`).
27    pub bank_name: Option<String>,
28    /// Two-letter ISO code representing the country the bank account is located in.
29    pub country: String,
30    /// Three-letter [ISO code for the currency](https://stripe.com/docs/payouts) paid out to the bank account.
31    pub currency: stripe_types::Currency,
32    /// The ID of the customer that the bank account is associated with.
33    pub customer: Option<stripe_types::Expandable<stripe_shared::Customer>>,
34    /// Whether this bank account is the default external account for its currency.
35    pub default_for_currency: Option<bool>,
36    /// Uniquely identifies this particular bank account.
37    /// You can use this attribute to check whether two bank accounts are the same.
38    pub fingerprint: Option<String>,
39    /// Information about the [upcoming new requirements for the bank account](https://docs.stripe.com/connect/custom-accounts/future-requirements), including what information needs to be collected, and by when.
40    pub future_requirements: Option<stripe_shared::ExternalAccountRequirements>,
41    /// Unique identifier for the object.
42    pub id: stripe_shared::BankAccountId,
43    /// The last four digits of the bank account number.
44    pub last4: String,
45    /// Set of [key-value pairs](https://docs.stripe.com/api/metadata) that you can attach to an object.
46    /// This can be useful for storing additional information about the object in a structured format.
47    pub metadata: Option<std::collections::HashMap<String, String>>,
48    /// Information about the requirements for the bank account, including what information needs to be collected.
49    pub requirements: Option<stripe_shared::ExternalAccountRequirements>,
50    /// The routing transit number for the bank account.
51    pub routing_number: Option<String>,
52    /// For bank accounts, possible values are `new`, `validated`, `verified`, `verification_failed`, `tokenized_account_number_deactivated` or `errored`.
53    /// A bank account that hasn't had any activity or validation performed is `new`.
54    /// If Stripe can determine that the bank account exists, its status will be `validated`.
55    /// Note that there often isn’t enough information to know (e.g., for smaller credit unions), and the validation is not always run.
56    /// If customer bank account verification has succeeded, the bank account status will be `verified`.
57    /// If the verification failed for any reason, such as microdeposit failure, the status will be `verification_failed`.
58    /// If the status is `tokenized_account_number_deactivated`, the account utilizes a tokenized account number which has been deactivated due to expiration or revocation.
59    /// This account will need to be reverified to continue using it for money movement.
60    /// If a payout sent to this bank account fails, we'll set the status to `errored` and will not continue to send [scheduled payouts](https://stripe.com/docs/payouts#payout-schedule) until the bank details are updated.
61    ///
62    /// For external accounts, possible values are `new`, `errored`, `verification_failed`, and `tokenized_account_number_deactivated`.
63    /// If a payout fails, the status is set to `errored` and scheduled payouts are stopped until account details are updated.
64    /// In the US and India, if we can't [verify the owner of the bank account](https://support.stripe.com/questions/bank-account-ownership-verification), we'll set the status to `verification_failed`.
65    /// Other validations aren't run against external accounts because they're only used for payouts.
66    /// This means the other statuses don't apply.
67    pub status: String,
68}
69#[cfg(feature = "redact-generated-debug")]
70impl std::fmt::Debug for BankAccount {
71    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
72        f.debug_struct("BankAccount").finish_non_exhaustive()
73    }
74}
75#[doc(hidden)]
76pub struct BankAccountBuilder {
77    account: Option<Option<stripe_types::Expandable<stripe_shared::Account>>>,
78    account_holder_name: Option<Option<String>>,
79    account_holder_type: Option<Option<String>>,
80    account_type: Option<Option<String>>,
81    available_payout_methods: Option<Option<Vec<BankAccountAvailablePayoutMethods>>>,
82    bank_name: Option<Option<String>>,
83    country: Option<String>,
84    currency: Option<stripe_types::Currency>,
85    customer: Option<Option<stripe_types::Expandable<stripe_shared::Customer>>>,
86    default_for_currency: Option<Option<bool>>,
87    fingerprint: Option<Option<String>>,
88    future_requirements: Option<Option<stripe_shared::ExternalAccountRequirements>>,
89    id: Option<stripe_shared::BankAccountId>,
90    last4: Option<String>,
91    metadata: Option<Option<std::collections::HashMap<String, String>>>,
92    requirements: Option<Option<stripe_shared::ExternalAccountRequirements>>,
93    routing_number: Option<Option<String>>,
94    status: Option<String>,
95}
96
97#[allow(
98    unused_variables,
99    irrefutable_let_patterns,
100    clippy::let_unit_value,
101    clippy::match_single_binding,
102    clippy::single_match
103)]
104const _: () = {
105    use miniserde::de::{Map, Visitor};
106    use miniserde::json::Value;
107    use miniserde::{Deserialize, Result, make_place};
108    use stripe_types::miniserde_helpers::FromValueOpt;
109    use stripe_types::{MapBuilder, ObjectDeser};
110
111    make_place!(Place);
112
113    impl Deserialize for BankAccount {
114        fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
115            Place::new(out)
116        }
117    }
118
119    struct Builder<'a> {
120        out: &'a mut Option<BankAccount>,
121        builder: BankAccountBuilder,
122    }
123
124    impl Visitor for Place<BankAccount> {
125        fn map(&mut self) -> Result<Box<dyn Map + '_>> {
126            Ok(Box::new(Builder {
127                out: &mut self.out,
128                builder: BankAccountBuilder::deser_default(),
129            }))
130        }
131    }
132
133    impl MapBuilder for BankAccountBuilder {
134        type Out = BankAccount;
135        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
136            Ok(match k {
137                "account" => Deserialize::begin(&mut self.account),
138                "account_holder_name" => Deserialize::begin(&mut self.account_holder_name),
139                "account_holder_type" => Deserialize::begin(&mut self.account_holder_type),
140                "account_type" => Deserialize::begin(&mut self.account_type),
141                "available_payout_methods" => {
142                    Deserialize::begin(&mut self.available_payout_methods)
143                }
144                "bank_name" => Deserialize::begin(&mut self.bank_name),
145                "country" => Deserialize::begin(&mut self.country),
146                "currency" => Deserialize::begin(&mut self.currency),
147                "customer" => Deserialize::begin(&mut self.customer),
148                "default_for_currency" => Deserialize::begin(&mut self.default_for_currency),
149                "fingerprint" => Deserialize::begin(&mut self.fingerprint),
150                "future_requirements" => Deserialize::begin(&mut self.future_requirements),
151                "id" => Deserialize::begin(&mut self.id),
152                "last4" => Deserialize::begin(&mut self.last4),
153                "metadata" => Deserialize::begin(&mut self.metadata),
154                "requirements" => Deserialize::begin(&mut self.requirements),
155                "routing_number" => Deserialize::begin(&mut self.routing_number),
156                "status" => Deserialize::begin(&mut self.status),
157                _ => <dyn Visitor>::ignore(),
158            })
159        }
160
161        fn deser_default() -> Self {
162            Self {
163                account: Some(None),
164                account_holder_name: Some(None),
165                account_holder_type: Some(None),
166                account_type: Some(None),
167                available_payout_methods: Some(None),
168                bank_name: Some(None),
169                country: None,
170                currency: None,
171                customer: Some(None),
172                default_for_currency: Some(None),
173                fingerprint: Some(None),
174                future_requirements: Some(None),
175                id: None,
176                last4: None,
177                metadata: Some(None),
178                requirements: Some(None),
179                routing_number: Some(None),
180                status: None,
181            }
182        }
183
184        fn take_out(&mut self) -> Option<Self::Out> {
185            let (
186                Some(account),
187                Some(account_holder_name),
188                Some(account_holder_type),
189                Some(account_type),
190                Some(available_payout_methods),
191                Some(bank_name),
192                Some(country),
193                Some(currency),
194                Some(customer),
195                Some(default_for_currency),
196                Some(fingerprint),
197                Some(future_requirements),
198                Some(id),
199                Some(last4),
200                Some(metadata),
201                Some(requirements),
202                Some(routing_number),
203                Some(status),
204            ) = (
205                self.account.take(),
206                self.account_holder_name.take(),
207                self.account_holder_type.take(),
208                self.account_type.take(),
209                self.available_payout_methods.take(),
210                self.bank_name.take(),
211                self.country.take(),
212                self.currency.take(),
213                self.customer.take(),
214                self.default_for_currency,
215                self.fingerprint.take(),
216                self.future_requirements.take(),
217                self.id.take(),
218                self.last4.take(),
219                self.metadata.take(),
220                self.requirements.take(),
221                self.routing_number.take(),
222                self.status.take(),
223            )
224            else {
225                return None;
226            };
227            Some(Self::Out {
228                account,
229                account_holder_name,
230                account_holder_type,
231                account_type,
232                available_payout_methods,
233                bank_name,
234                country,
235                currency,
236                customer,
237                default_for_currency,
238                fingerprint,
239                future_requirements,
240                id,
241                last4,
242                metadata,
243                requirements,
244                routing_number,
245                status,
246            })
247        }
248    }
249
250    impl Map for Builder<'_> {
251        fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
252            self.builder.key(k)
253        }
254
255        fn finish(&mut self) -> Result<()> {
256            *self.out = self.builder.take_out();
257            Ok(())
258        }
259    }
260
261    impl ObjectDeser for BankAccount {
262        type Builder = BankAccountBuilder;
263    }
264
265    impl FromValueOpt for BankAccount {
266        fn from_value(v: Value) -> Option<Self> {
267            let Value::Object(obj) = v else {
268                return None;
269            };
270            let mut b = BankAccountBuilder::deser_default();
271            for (k, v) in obj {
272                match k.as_str() {
273                    "account" => b.account = FromValueOpt::from_value(v),
274                    "account_holder_name" => b.account_holder_name = FromValueOpt::from_value(v),
275                    "account_holder_type" => b.account_holder_type = FromValueOpt::from_value(v),
276                    "account_type" => b.account_type = FromValueOpt::from_value(v),
277                    "available_payout_methods" => {
278                        b.available_payout_methods = FromValueOpt::from_value(v)
279                    }
280                    "bank_name" => b.bank_name = FromValueOpt::from_value(v),
281                    "country" => b.country = FromValueOpt::from_value(v),
282                    "currency" => b.currency = FromValueOpt::from_value(v),
283                    "customer" => b.customer = FromValueOpt::from_value(v),
284                    "default_for_currency" => b.default_for_currency = FromValueOpt::from_value(v),
285                    "fingerprint" => b.fingerprint = FromValueOpt::from_value(v),
286                    "future_requirements" => b.future_requirements = FromValueOpt::from_value(v),
287                    "id" => b.id = FromValueOpt::from_value(v),
288                    "last4" => b.last4 = FromValueOpt::from_value(v),
289                    "metadata" => b.metadata = FromValueOpt::from_value(v),
290                    "requirements" => b.requirements = FromValueOpt::from_value(v),
291                    "routing_number" => b.routing_number = FromValueOpt::from_value(v),
292                    "status" => b.status = FromValueOpt::from_value(v),
293                    _ => {}
294                }
295            }
296            b.take_out()
297        }
298    }
299};
300#[cfg(feature = "serialize")]
301impl serde::Serialize for BankAccount {
302    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
303        use serde::ser::SerializeStruct;
304        let mut s = s.serialize_struct("BankAccount", 19)?;
305        s.serialize_field("account", &self.account)?;
306        s.serialize_field("account_holder_name", &self.account_holder_name)?;
307        s.serialize_field("account_holder_type", &self.account_holder_type)?;
308        s.serialize_field("account_type", &self.account_type)?;
309        s.serialize_field("available_payout_methods", &self.available_payout_methods)?;
310        s.serialize_field("bank_name", &self.bank_name)?;
311        s.serialize_field("country", &self.country)?;
312        s.serialize_field("currency", &self.currency)?;
313        s.serialize_field("customer", &self.customer)?;
314        s.serialize_field("default_for_currency", &self.default_for_currency)?;
315        s.serialize_field("fingerprint", &self.fingerprint)?;
316        s.serialize_field("future_requirements", &self.future_requirements)?;
317        s.serialize_field("id", &self.id)?;
318        s.serialize_field("last4", &self.last4)?;
319        s.serialize_field("metadata", &self.metadata)?;
320        s.serialize_field("requirements", &self.requirements)?;
321        s.serialize_field("routing_number", &self.routing_number)?;
322        s.serialize_field("status", &self.status)?;
323
324        s.serialize_field("object", "bank_account")?;
325        s.end()
326    }
327}
328/// A set of available payout methods for this bank account.
329/// Only values from this set should be passed as the `method` when creating a payout.
330#[derive(Clone, Eq, PartialEq)]
331#[non_exhaustive]
332pub enum BankAccountAvailablePayoutMethods {
333    Instant,
334    Standard,
335    /// An unrecognized value from Stripe. Should not be used as a request parameter.
336    Unknown(String),
337}
338impl BankAccountAvailablePayoutMethods {
339    pub fn as_str(&self) -> &str {
340        use BankAccountAvailablePayoutMethods::*;
341        match self {
342            Instant => "instant",
343            Standard => "standard",
344            Unknown(v) => v,
345        }
346    }
347}
348
349impl std::str::FromStr for BankAccountAvailablePayoutMethods {
350    type Err = std::convert::Infallible;
351    fn from_str(s: &str) -> Result<Self, Self::Err> {
352        use BankAccountAvailablePayoutMethods::*;
353        match s {
354            "instant" => Ok(Instant),
355            "standard" => Ok(Standard),
356            v => {
357                tracing::warn!(
358                    "Unknown value '{}' for enum '{}'",
359                    v,
360                    "BankAccountAvailablePayoutMethods"
361                );
362                Ok(Unknown(v.to_owned()))
363            }
364        }
365    }
366}
367impl std::fmt::Display for BankAccountAvailablePayoutMethods {
368    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
369        f.write_str(self.as_str())
370    }
371}
372
373#[cfg(not(feature = "redact-generated-debug"))]
374impl std::fmt::Debug for BankAccountAvailablePayoutMethods {
375    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
376        f.write_str(self.as_str())
377    }
378}
379#[cfg(feature = "redact-generated-debug")]
380impl std::fmt::Debug for BankAccountAvailablePayoutMethods {
381    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
382        f.debug_struct(stringify!(BankAccountAvailablePayoutMethods)).finish_non_exhaustive()
383    }
384}
385#[cfg(feature = "serialize")]
386impl serde::Serialize for BankAccountAvailablePayoutMethods {
387    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
388    where
389        S: serde::Serializer,
390    {
391        serializer.serialize_str(self.as_str())
392    }
393}
394impl miniserde::Deserialize for BankAccountAvailablePayoutMethods {
395    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
396        crate::Place::new(out)
397    }
398}
399
400impl miniserde::de::Visitor for crate::Place<BankAccountAvailablePayoutMethods> {
401    fn string(&mut self, s: &str) -> miniserde::Result<()> {
402        use std::str::FromStr;
403        self.out = Some(BankAccountAvailablePayoutMethods::from_str(s).expect("infallible"));
404        Ok(())
405    }
406}
407
408stripe_types::impl_from_val_with_from_str!(BankAccountAvailablePayoutMethods);
409#[cfg(feature = "deserialize")]
410impl<'de> serde::Deserialize<'de> for BankAccountAvailablePayoutMethods {
411    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
412        use std::str::FromStr;
413        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
414        Ok(Self::from_str(&s).expect("infallible"))
415    }
416}
417impl stripe_types::Object for BankAccount {
418    type Id = stripe_shared::BankAccountId;
419    fn id(&self) -> &Self::Id {
420        &self.id
421    }
422
423    fn into_id(self) -> Self::Id {
424        self.id
425    }
426}
427stripe_types::def_id!(BankAccountId);