use serde::{Deserialize, Serialize};
use crate::client::{Client, Response};
use crate::ids::{BankAccountId, CardId, CustomerId, PaymentSourceId};
use crate::params::{Deleted, Expand, List, SearchList};
use crate::resources::{
BankAccount, Customer, PaymentMethod, PaymentSource, PaymentSourceParams, Source,
};
#[derive(Clone, Debug, Serialize, Eq, PartialEq)]
pub struct CustomerPaymentMethodRetrieval<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
pub ending_before: Option<String>,
#[serde(skip_serializing_if = "Expand::is_empty")]
pub expand: &'a [&'a str],
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<i32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub starting_after: Option<String>,
#[serde(rename = "type")]
#[serde(skip_serializing_if = "Option::is_none")]
pub type_: Option<CustomerPaymentMethodRetrievalType>,
}
impl<'a> CustomerPaymentMethodRetrieval<'a> {
pub fn new() -> Self {
CustomerPaymentMethodRetrieval {
ending_before: None,
expand: &[],
limit: None,
starting_after: None,
type_: None,
}
}
}
#[derive(Copy, Clone, Debug, Serialize, Eq, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum CustomerPaymentMethodRetrievalType {
AcssDebit,
AfterpayClearpay,
Alipay,
AuBecsDebit,
BacsDebit,
Bancontact,
Boleto,
Card,
Eps,
Fpx,
Giropay,
Grabpay,
Ideal,
Klarna,
Oxxo,
P24,
SepaDebit,
Sofort,
WechatPay,
}
#[derive(Clone, Debug, Default, Serialize)]
pub struct CustomerSearchParams<'a> {
pub query: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub page: Option<u64>,
pub expand: &'a [&'a str],
}
impl<'a> CustomerSearchParams<'a> {
pub fn new() -> CustomerSearchParams<'a> {
CustomerSearchParams { query: String::new(), limit: None, page: None, expand: &[] }
}
}
impl Customer {
pub fn attach_source(
client: &Client,
customer_id: &CustomerId,
source: PaymentSourceParams,
) -> Response<PaymentSource> {
#[derive(Serialize)]
struct AttachSource {
source: PaymentSourceParams,
}
let params = AttachSource { source };
client.post_form(&format!("/customers/{}/sources", customer_id), params)
}
pub fn detach_source(
client: &Client,
customer_id: &CustomerId,
source_id: &PaymentSourceId,
) -> Response<DetachedSource> {
client.delete(&format!("/customers/{}/sources/{}", customer_id, source_id))
}
pub fn retrieve_source(
client: &Client,
customer_id: &CustomerId,
source_id: &PaymentSourceId,
) -> Response<PaymentSource> {
client.get(&format!("/customers/{}/sources/{}", customer_id, source_id))
}
pub fn verify_bank_account(
client: &Client,
customer_id: &CustomerId,
bank_account_id: &BankAccountId,
params: VerifyBankAccount<'_>,
) -> Response<BankAccount> {
client.post_form(
&format!("/customers/{}/sources/{}/verify", customer_id, bank_account_id),
params,
)
}
pub fn retrieve_payment_methods(
client: &Client,
customer_id: &CustomerId,
params: CustomerPaymentMethodRetrieval<'_>,
) -> Response<List<PaymentMethod>> {
#[allow(clippy::needless_borrows_for_generic_args)]
client.get_query(&format!("/customers/{}/payment_methods", customer_id), ¶ms)
}
pub fn search(client: &Client, params: CustomerSearchParams) -> Response<SearchList<Customer>> {
client.get_query("/customers/search", params)
}
}
#[derive(Clone, Debug, Default, Serialize)]
pub struct VerifyBankAccount<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
pub amounts: Option<Vec<i64>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub verification_method: Option<&'a str>,
}
impl VerifyBankAccount<'_> {
pub fn new() -> Self {
VerifyBankAccount { amounts: None, verification_method: None }
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(tag = "object", rename_all = "snake_case")]
pub enum DetachedSource {
BankAccount(Deleted<BankAccountId>),
Card(Deleted<CardId>),
Source(Source),
}