1use serde::{Deserialize, Serialize};
2
3use crate::client::{Client, Response};
4use crate::ids::{BankAccountId, CardId, CustomerId, PaymentSourceId};
5use crate::params::{Deleted, Expand, List, SearchList};
6use crate::resources::{
7 BankAccount, Customer, PaymentMethod, PaymentSource, PaymentSourceParams, Source,
8};
9
10#[derive(Clone, Debug, Serialize, Default, Eq, PartialEq)]
11pub struct CustomerPaymentMethodRetrieval<'a> {
12 #[serde(skip_serializing_if = "Option::is_none")]
16 pub ending_before: Option<String>,
17
18 #[serde(skip_serializing_if = "Expand::is_empty")]
20 pub expand: &'a [&'a str],
21
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub limit: Option<i32>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
30 pub starting_after: Option<String>,
31
32 #[serde(rename = "type")]
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub type_: Option<CustomerPaymentMethodRetrievalType>,
36}
37
38impl<'a> CustomerPaymentMethodRetrieval<'a> {
39 pub fn new() -> Self {
40 CustomerPaymentMethodRetrieval::default()
41 }
42}
43
44#[derive(Copy, Clone, Debug, Serialize, Eq, PartialEq)]
45#[serde(rename_all = "snake_case")]
46pub enum CustomerPaymentMethodRetrievalType {
47 AcssDebit,
48 AfterpayClearpay,
49 Alipay,
50 AuBecsDebit,
51 BacsDebit,
52 Bancontact,
53 Boleto,
54 Card,
55 Eps,
56 Fpx,
57 Giropay,
58 Grabpay,
59 Ideal,
60 Klarna,
61 Oxxo,
62 P24,
63 SepaDebit,
64 Sofort,
65 WechatPay,
66}
67
68#[derive(Clone, Debug, Default, Serialize)]
69pub struct CustomerSearchParams<'a> {
70 pub query: String,
71 #[serde(skip_serializing_if = "Option::is_none")]
72 pub limit: Option<u64>,
73 #[serde(skip_serializing_if = "Option::is_none")]
74 pub page: Option<u64>,
75 pub expand: &'a [&'a str],
76}
77
78impl<'a> CustomerSearchParams<'a> {
79 pub fn new() -> CustomerSearchParams<'a> {
80 CustomerSearchParams::default()
81 }
82}
83
84impl Customer {
85 pub fn attach_source(
89 client: &Client,
90 customer_id: &CustomerId,
91 source: PaymentSourceParams,
92 ) -> Response<PaymentSource> {
93 #[derive(Serialize)]
94 struct AttachSource {
95 source: PaymentSourceParams,
96 }
97 let params = AttachSource { source };
98 client.post_form(&format!("/customers/{}/sources", customer_id), params)
99 }
100
101 pub fn detach_source(
105 client: &Client,
106 customer_id: &CustomerId,
107 source_id: &PaymentSourceId,
108 ) -> Response<DetachedSource> {
109 client.delete(&format!("/customers/{}/sources/{}", customer_id, source_id))
110 }
111
112 pub fn retrieve_source(
114 client: &Client,
115 customer_id: &CustomerId,
116 source_id: &PaymentSourceId,
117 ) -> Response<PaymentSource> {
118 client.get(&format!("/customers/{}/sources/{}", customer_id, source_id))
119 }
120
121 pub fn verify_bank_account(
125 client: &Client,
126 customer_id: &CustomerId,
127 bank_account_id: &BankAccountId,
128 params: VerifyBankAccount<'_>,
129 ) -> Response<BankAccount> {
130 client.post_form(
131 &format!("/customers/{}/sources/{}/verify", customer_id, bank_account_id),
132 params,
133 )
134 }
135
136 pub fn retrieve_payment_methods(
140 client: &Client,
141 customer_id: &CustomerId,
142 params: CustomerPaymentMethodRetrieval<'_>,
143 ) -> Response<List<PaymentMethod>> {
144 #[allow(clippy::needless_borrows_for_generic_args)]
145 client.get_query(&format!("/customers/{}/payment_methods", customer_id), ¶ms)
146 }
147
148 pub fn search(client: &Client, params: CustomerSearchParams) -> Response<SearchList<Customer>> {
152 client.get_query("/customers/search", params)
153 }
154}
155
156#[derive(Clone, Debug, Default, Serialize)]
160pub struct VerifyBankAccount<'a> {
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub amounts: Option<Vec<i64>>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub verification_method: Option<&'a str>,
165}
166
167impl VerifyBankAccount<'_> {
168 pub fn new() -> Self {
169 VerifyBankAccount { amounts: None, verification_method: None }
170 }
171}
172
173#[derive(Clone, Debug, Deserialize, Serialize)]
174#[serde(tag = "object", rename_all = "snake_case")]
175pub enum DetachedSource {
176 BankAccount(Deleted<BankAccountId>),
177 Card(Deleted<CardId>),
178 Source(Source),
179}