payjp_core/
card.rs

1/// クレジットカードの情報を表すcardオブジェクト
2///
3/// For more details see <<https://pay.jp/docs/api>>.
4#[derive(Clone,Debug,)]#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
5pub struct Card {
6    /// 請求先住所(市区町村)
7pub address_city: Option<String>,
8    /// 請求先住所(番地)
9pub address_line1: Option<String>,
10    /// 請求先住所(建物名)
11pub address_line2: Option<String>,
12    /// 請求先住所(都道府県)
13pub address_state: Option<String>,
14    /// 請求先住所(郵便番号)
15pub address_zip: Option<String>,
16    /// 郵便番号の検証結果
17pub address_zip_check: Option<CardAddressZipCheck>,
18    /// カードブランド名
19pub brand: CardBrand,
20    /// 2桁のISOコード(e.g. JP)
21pub country: Option<String>,
22    /// カード作成時のタイムスタンプ
23pub created: i64,
24    /// このカードを保有する顧客ID
25pub customer: Option<String>,
26    /// セキュリティコードの検証結果
27pub cvc_check: Option<CardCvcCheck>,
28    /// メールアドレス
29        /// 2024年8月以降、3Dセキュア認証の際にphoneまたはemailのデータ入力が求められます。.
30pub email: Option<String>,
31    /// 有効期限月
32pub exp_month: i64,
33    /// 有効期限年
34pub exp_year: i64,
35    /// このクレジットカード番号に紐づく値。
36        /// 同一番号のカードからは同一の値が生成されることが保証されており、 トークン化の度にトークンIDは変わりますが、この値は変わりません。.
37pub fingerprint: String,
38    /// car_で始まり一意なオブジェクトを示す文字列
39pub id: payjp_core::CardId,
40    /// カード番号の下四桁
41pub last4: String,
42    /// 本番環境かどうか
43pub livemode: bool,
44pub metadata: Option<payjp_shared::Metadata>,
45    /// カード保有者名
46pub name: Option<String>,
47    /// E.164形式の電話番号 (e.g. 090-0123-4567(日本) => "+819001234567")
48        /// 2024年8月以降、3Dセキュア認証の際にphoneまたはemailのデータ入力が求められます。.
49pub phone: Option<String>,
50    /// 3Dセキュアの利用状況
51pub three_d_secure_status: Option<CardThreeDSecureStatus>,
52
53}
54#[doc(hidden)]
55pub struct CardBuilder {
56    address_city: Option<Option<String>>,
57address_line1: Option<Option<String>>,
58address_line2: Option<Option<String>>,
59address_state: Option<Option<String>>,
60address_zip: Option<Option<String>>,
61address_zip_check: Option<Option<CardAddressZipCheck>>,
62brand: Option<CardBrand>,
63country: Option<Option<String>>,
64created: Option<i64>,
65customer: Option<Option<String>>,
66cvc_check: Option<Option<CardCvcCheck>>,
67email: Option<Option<String>>,
68exp_month: Option<i64>,
69exp_year: Option<i64>,
70fingerprint: Option<String>,
71id: Option<payjp_core::CardId>,
72last4: Option<String>,
73livemode: Option<bool>,
74metadata: Option<Option<payjp_shared::Metadata>>,
75name: Option<Option<String>>,
76phone: Option<Option<String>>,
77three_d_secure_status: Option<Option<CardThreeDSecureStatus>>,
78
79}
80
81#[allow(unused_variables, irrefutable_let_patterns, clippy::let_unit_value, clippy::match_single_binding, clippy::single_match)]
82const _: () = {
83    use miniserde::de::{Map, Visitor};
84    use miniserde::json::Value;
85    use miniserde::{make_place, Deserialize, Result};
86    use payjp_types::{MapBuilder, ObjectDeser};
87    use payjp_types::miniserde_helpers::FromValueOpt;
88
89    make_place!(Place);
90
91    impl Deserialize for Card {
92    fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
93       Place::new(out)
94    }
95}
96
97struct Builder<'a> {
98    out: &'a mut Option<Card>,
99    builder: CardBuilder,
100}
101
102impl Visitor for Place<Card> {
103    fn map(&mut self) -> Result<Box<dyn Map + '_>> {
104        Ok(Box::new(Builder {
105            out: &mut self.out,
106            builder: CardBuilder::deser_default(),
107        }))
108    }
109}
110
111impl MapBuilder for CardBuilder {
112    type Out = Card;
113    fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
114        Ok(match k {
115            "address_city" => Deserialize::begin(&mut self.address_city),
116"address_line1" => Deserialize::begin(&mut self.address_line1),
117"address_line2" => Deserialize::begin(&mut self.address_line2),
118"address_state" => Deserialize::begin(&mut self.address_state),
119"address_zip" => Deserialize::begin(&mut self.address_zip),
120"address_zip_check" => Deserialize::begin(&mut self.address_zip_check),
121"brand" => Deserialize::begin(&mut self.brand),
122"country" => Deserialize::begin(&mut self.country),
123"created" => Deserialize::begin(&mut self.created),
124"customer" => Deserialize::begin(&mut self.customer),
125"cvc_check" => Deserialize::begin(&mut self.cvc_check),
126"email" => Deserialize::begin(&mut self.email),
127"exp_month" => Deserialize::begin(&mut self.exp_month),
128"exp_year" => Deserialize::begin(&mut self.exp_year),
129"fingerprint" => Deserialize::begin(&mut self.fingerprint),
130"id" => Deserialize::begin(&mut self.id),
131"last4" => Deserialize::begin(&mut self.last4),
132"livemode" => Deserialize::begin(&mut self.livemode),
133"metadata" => Deserialize::begin(&mut self.metadata),
134"name" => Deserialize::begin(&mut self.name),
135"phone" => Deserialize::begin(&mut self.phone),
136"three_d_secure_status" => Deserialize::begin(&mut self.three_d_secure_status),
137
138            _ => <dyn Visitor>::ignore(),
139        })
140    }
141
142    fn deser_default() -> Self {
143        Self {
144            address_city: Deserialize::default(),
145address_line1: Deserialize::default(),
146address_line2: Deserialize::default(),
147address_state: Deserialize::default(),
148address_zip: Deserialize::default(),
149address_zip_check: Deserialize::default(),
150brand: Deserialize::default(),
151country: Deserialize::default(),
152created: Deserialize::default(),
153customer: Deserialize::default(),
154cvc_check: Deserialize::default(),
155email: Deserialize::default(),
156exp_month: Deserialize::default(),
157exp_year: Deserialize::default(),
158fingerprint: Deserialize::default(),
159id: Deserialize::default(),
160last4: Deserialize::default(),
161livemode: Deserialize::default(),
162metadata: Deserialize::default(),
163name: Deserialize::default(),
164phone: Deserialize::default(),
165three_d_secure_status: Deserialize::default(),
166
167        }
168    }
169
170    fn take_out(&mut self) -> Option<Self::Out> {
171        let (Some(address_city),
172Some(address_line1),
173Some(address_line2),
174Some(address_state),
175Some(address_zip),
176Some(address_zip_check),
177Some(brand),
178Some(country),
179Some(created),
180Some(customer),
181Some(cvc_check),
182Some(email),
183Some(exp_month),
184Some(exp_year),
185Some(fingerprint),
186Some(id),
187Some(last4),
188Some(livemode),
189Some(metadata),
190Some(name),
191Some(phone),
192Some(three_d_secure_status),
193) = (self.address_city.take(),
194self.address_line1.take(),
195self.address_line2.take(),
196self.address_state.take(),
197self.address_zip.take(),
198self.address_zip_check,
199self.brand,
200self.country.take(),
201self.created,
202self.customer.take(),
203self.cvc_check,
204self.email.take(),
205self.exp_month,
206self.exp_year,
207self.fingerprint.take(),
208self.id.take(),
209self.last4.take(),
210self.livemode,
211self.metadata,
212self.name.take(),
213self.phone.take(),
214self.three_d_secure_status,
215) else {
216            return None;
217        };
218        Some(Self::Out { address_city,address_line1,address_line2,address_state,address_zip,address_zip_check,brand,country,created,customer,cvc_check,email,exp_month,exp_year,fingerprint,id,last4,livemode,metadata,name,phone,three_d_secure_status })
219    }
220}
221
222impl<'a> Map for Builder<'a> {
223    fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
224        self.builder.key(k)
225    }
226
227    fn finish(&mut self) -> Result<()> {
228        *self.out = self.builder.take_out();
229        Ok(())
230    }
231}
232
233impl ObjectDeser for Card {
234    type Builder = CardBuilder;
235}
236
237impl FromValueOpt for Card {
238    fn from_value(v: Value) -> Option<Self> {
239        let Value::Object(obj) = v else {
240            return None;
241        };
242        let mut b = CardBuilder::deser_default();
243        for (k, v) in obj {
244            match k.as_str() {
245                "address_city" => b.address_city = FromValueOpt::from_value(v),
246"address_line1" => b.address_line1 = FromValueOpt::from_value(v),
247"address_line2" => b.address_line2 = FromValueOpt::from_value(v),
248"address_state" => b.address_state = FromValueOpt::from_value(v),
249"address_zip" => b.address_zip = FromValueOpt::from_value(v),
250"address_zip_check" => b.address_zip_check = FromValueOpt::from_value(v),
251"brand" => b.brand = FromValueOpt::from_value(v),
252"country" => b.country = FromValueOpt::from_value(v),
253"created" => b.created = FromValueOpt::from_value(v),
254"customer" => b.customer = FromValueOpt::from_value(v),
255"cvc_check" => b.cvc_check = FromValueOpt::from_value(v),
256"email" => b.email = FromValueOpt::from_value(v),
257"exp_month" => b.exp_month = FromValueOpt::from_value(v),
258"exp_year" => b.exp_year = FromValueOpt::from_value(v),
259"fingerprint" => b.fingerprint = FromValueOpt::from_value(v),
260"id" => b.id = FromValueOpt::from_value(v),
261"last4" => b.last4 = FromValueOpt::from_value(v),
262"livemode" => b.livemode = FromValueOpt::from_value(v),
263"metadata" => b.metadata = FromValueOpt::from_value(v),
264"name" => b.name = FromValueOpt::from_value(v),
265"phone" => b.phone = FromValueOpt::from_value(v),
266"three_d_secure_status" => b.three_d_secure_status = FromValueOpt::from_value(v),
267
268                _ => {}
269            }
270        }
271        b.take_out()
272    }
273}
274
275};
276#[cfg(feature = "serialize")]
277impl serde::Serialize for Card {
278    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
279        use serde::ser::SerializeStruct;
280        let mut s = s.serialize_struct("Card", 23)?;
281        s.serialize_field("address_city", &self.address_city)?;
282s.serialize_field("address_line1", &self.address_line1)?;
283s.serialize_field("address_line2", &self.address_line2)?;
284s.serialize_field("address_state", &self.address_state)?;
285s.serialize_field("address_zip", &self.address_zip)?;
286s.serialize_field("address_zip_check", &self.address_zip_check)?;
287s.serialize_field("brand", &self.brand)?;
288s.serialize_field("country", &self.country)?;
289s.serialize_field("created", &self.created)?;
290s.serialize_field("customer", &self.customer)?;
291s.serialize_field("cvc_check", &self.cvc_check)?;
292s.serialize_field("email", &self.email)?;
293s.serialize_field("exp_month", &self.exp_month)?;
294s.serialize_field("exp_year", &self.exp_year)?;
295s.serialize_field("fingerprint", &self.fingerprint)?;
296s.serialize_field("id", &self.id)?;
297s.serialize_field("last4", &self.last4)?;
298s.serialize_field("livemode", &self.livemode)?;
299s.serialize_field("metadata", &self.metadata)?;
300s.serialize_field("name", &self.name)?;
301s.serialize_field("phone", &self.phone)?;
302s.serialize_field("three_d_secure_status", &self.three_d_secure_status)?;
303
304        s.serialize_field("object", "card")?;
305        s.end()
306    }
307}
308/// 郵便番号の検証結果
309#[derive(Copy,Clone,Eq, PartialEq,)]pub enum CardAddressZipCheck {
310Passed,
311Failed,
312Unchecked,
313
314}
315impl CardAddressZipCheck {
316    pub fn as_str(self) -> &'static str {
317        use CardAddressZipCheck::*;
318        match self {
319Passed => "passed",
320Failed => "failed",
321Unchecked => "unchecked",
322
323        }
324    }
325}
326
327impl std::str::FromStr for CardAddressZipCheck {
328    type Err = payjp_types::ParseError;
329    fn from_str(s: &str) -> Result<Self, Self::Err> {
330        use CardAddressZipCheck::*;
331        match s {
332    "passed" => Ok(Passed),
333"failed" => Ok(Failed),
334"unchecked" => Ok(Unchecked),
335_ => Err(payjp_types::ParseError)
336
337        }
338    }
339}
340impl std::fmt::Display for CardAddressZipCheck {
341    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
342        f.write_str(self.as_str())
343    }
344}
345
346impl std::fmt::Debug for CardAddressZipCheck {
347    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
348        f.write_str(self.as_str())
349    }
350}
351#[cfg(feature = "serialize")]
352impl serde::Serialize for CardAddressZipCheck {
353    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
354        serializer.serialize_str(self.as_str())
355    }
356}
357impl miniserde::Deserialize for CardAddressZipCheck {
358    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
359        crate::Place::new(out)
360    }
361}
362
363impl miniserde::de::Visitor for crate::Place<CardAddressZipCheck> {
364    fn string(&mut self, s: &str) -> miniserde::Result<()> {
365        use std::str::FromStr;
366        self.out = Some(CardAddressZipCheck::from_str(s).map_err(|_| miniserde::Error)?);
367        Ok(())
368    }
369}
370
371payjp_types::impl_from_val_with_from_str!(CardAddressZipCheck);
372#[cfg(feature = "deserialize")]
373impl<'de> serde::Deserialize<'de> for CardAddressZipCheck {
374    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
375        use std::str::FromStr;
376        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
377        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for CardAddressZipCheck"))
378    }
379}
380/// カードブランド名
381#[derive(Copy,Clone,Eq, PartialEq,)]pub enum CardBrand {
382Visa,
383MasterCard,
384Jcb,
385AmericanExpress,
386DinersClub,
387Discover,
388
389}
390impl CardBrand {
391    pub fn as_str(self) -> &'static str {
392        use CardBrand::*;
393        match self {
394Visa => "Visa",
395MasterCard => "MasterCard",
396Jcb => "JCB",
397AmericanExpress => "American Express",
398DinersClub => "Diners Club",
399Discover => "Discover",
400
401        }
402    }
403}
404
405impl std::str::FromStr for CardBrand {
406    type Err = payjp_types::ParseError;
407    fn from_str(s: &str) -> Result<Self, Self::Err> {
408        use CardBrand::*;
409        match s {
410    "Visa" => Ok(Visa),
411"MasterCard" => Ok(MasterCard),
412"JCB" => Ok(Jcb),
413"American Express" => Ok(AmericanExpress),
414"Diners Club" => Ok(DinersClub),
415"Discover" => Ok(Discover),
416_ => Err(payjp_types::ParseError)
417
418        }
419    }
420}
421impl std::fmt::Display for CardBrand {
422    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
423        f.write_str(self.as_str())
424    }
425}
426
427impl std::fmt::Debug for CardBrand {
428    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
429        f.write_str(self.as_str())
430    }
431}
432#[cfg(feature = "serialize")]
433impl serde::Serialize for CardBrand {
434    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
435        serializer.serialize_str(self.as_str())
436    }
437}
438impl miniserde::Deserialize for CardBrand {
439    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
440        crate::Place::new(out)
441    }
442}
443
444impl miniserde::de::Visitor for crate::Place<CardBrand> {
445    fn string(&mut self, s: &str) -> miniserde::Result<()> {
446        use std::str::FromStr;
447        self.out = Some(CardBrand::from_str(s).map_err(|_| miniserde::Error)?);
448        Ok(())
449    }
450}
451
452payjp_types::impl_from_val_with_from_str!(CardBrand);
453#[cfg(feature = "deserialize")]
454impl<'de> serde::Deserialize<'de> for CardBrand {
455    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
456        use std::str::FromStr;
457        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
458        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for CardBrand"))
459    }
460}
461/// セキュリティコードの検証結果
462#[derive(Copy,Clone,Eq, PartialEq,)]pub enum CardCvcCheck {
463Passed,
464Failed,
465Unchecked,
466
467}
468impl CardCvcCheck {
469    pub fn as_str(self) -> &'static str {
470        use CardCvcCheck::*;
471        match self {
472Passed => "passed",
473Failed => "failed",
474Unchecked => "unchecked",
475
476        }
477    }
478}
479
480impl std::str::FromStr for CardCvcCheck {
481    type Err = payjp_types::ParseError;
482    fn from_str(s: &str) -> Result<Self, Self::Err> {
483        use CardCvcCheck::*;
484        match s {
485    "passed" => Ok(Passed),
486"failed" => Ok(Failed),
487"unchecked" => Ok(Unchecked),
488_ => Err(payjp_types::ParseError)
489
490        }
491    }
492}
493impl std::fmt::Display for CardCvcCheck {
494    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
495        f.write_str(self.as_str())
496    }
497}
498
499impl std::fmt::Debug for CardCvcCheck {
500    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
501        f.write_str(self.as_str())
502    }
503}
504#[cfg(feature = "serialize")]
505impl serde::Serialize for CardCvcCheck {
506    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
507        serializer.serialize_str(self.as_str())
508    }
509}
510impl miniserde::Deserialize for CardCvcCheck {
511    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
512        crate::Place::new(out)
513    }
514}
515
516impl miniserde::de::Visitor for crate::Place<CardCvcCheck> {
517    fn string(&mut self, s: &str) -> miniserde::Result<()> {
518        use std::str::FromStr;
519        self.out = Some(CardCvcCheck::from_str(s).map_err(|_| miniserde::Error)?);
520        Ok(())
521    }
522}
523
524payjp_types::impl_from_val_with_from_str!(CardCvcCheck);
525#[cfg(feature = "deserialize")]
526impl<'de> serde::Deserialize<'de> for CardCvcCheck {
527    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
528        use std::str::FromStr;
529        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
530        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for CardCvcCheck"))
531    }
532}
533/// 3Dセキュアの利用状況
534#[derive(Copy,Clone,Eq, PartialEq,)]pub enum CardThreeDSecureStatus {
535Available,
536Unavailable,
537
538}
539impl CardThreeDSecureStatus {
540    pub fn as_str(self) -> &'static str {
541        use CardThreeDSecureStatus::*;
542        match self {
543Available => "available",
544Unavailable => "unavailable",
545
546        }
547    }
548}
549
550impl std::str::FromStr for CardThreeDSecureStatus {
551    type Err = payjp_types::ParseError;
552    fn from_str(s: &str) -> Result<Self, Self::Err> {
553        use CardThreeDSecureStatus::*;
554        match s {
555    "available" => Ok(Available),
556"unavailable" => Ok(Unavailable),
557_ => Err(payjp_types::ParseError)
558
559        }
560    }
561}
562impl std::fmt::Display for CardThreeDSecureStatus {
563    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
564        f.write_str(self.as_str())
565    }
566}
567
568impl std::fmt::Debug for CardThreeDSecureStatus {
569    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
570        f.write_str(self.as_str())
571    }
572}
573#[cfg(feature = "serialize")]
574impl serde::Serialize for CardThreeDSecureStatus {
575    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
576        serializer.serialize_str(self.as_str())
577    }
578}
579impl miniserde::Deserialize for CardThreeDSecureStatus {
580    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
581        crate::Place::new(out)
582    }
583}
584
585impl miniserde::de::Visitor for crate::Place<CardThreeDSecureStatus> {
586    fn string(&mut self, s: &str) -> miniserde::Result<()> {
587        use std::str::FromStr;
588        self.out = Some(CardThreeDSecureStatus::from_str(s).map_err(|_| miniserde::Error)?);
589        Ok(())
590    }
591}
592
593payjp_types::impl_from_val_with_from_str!(CardThreeDSecureStatus);
594#[cfg(feature = "deserialize")]
595impl<'de> serde::Deserialize<'de> for CardThreeDSecureStatus {
596    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
597        use std::str::FromStr;
598        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
599        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for CardThreeDSecureStatus"))
600    }
601}
602impl payjp_types::Object for Card {
603    type Id = payjp_core::CardId;
604    fn id(&self) -> &Self::Id {
605        &self.id
606    }
607
608    fn into_id(self) -> Self::Id {
609        self.id
610    }
611}
612payjp_types::def_id!(CardId);