flutterwave_v3_models/charge/direct_charge/
mod.rs1use crate::{
2 common::{charge_res_data::ChargeResData, payload::Payload},
3 fwcall::{FwCall, ToFwCall},
4};
5use chrono::NaiveDateTime;
6use serde::{Deserialize, Serialize};
7use std::{borrow::Cow, collections::HashMap};
8use validator::Validate;
9
10#[derive(Debug, Serialize, Deserialize, Validate)]
11pub struct CardChargeReq {
12 #[validate(credit_card)]
13 pub card_number: String,
14 #[validate(length(min = 3, max = 4))]
15 pub cvv: String,
16 #[validate(length(min = 2, max = 2))]
17 pub expiry_month: String,
18 #[validate(length(min = 2, max = 2))]
19 pub expiry_year: String,
20 #[validate(length(min = 3, max = 3))]
21 pub currency: Option<String>,
22 pub amount: String,
23 #[validate(email, length(max = 100))]
24 pub email: String,
25 pub fullname: Option<String>,
26 #[validate(phone, length(max = 50))]
27 pub phone_number: Option<String>,
28 #[validate(length(max = 100))]
29 pub tx_ref: String,
30 pub preauthorize: Option<bool>,
31 #[validate(url)]
32 pub redirect_url: Option<String>,
33 pub client_ip: Option<String>,
34 pub device_fingerprint: Option<String>,
35 pub payment_plan: Option<String>,
36 pub a_statusreasoncode: String,
37 pub is_custom_3ds_enabled: bool,
38 pub a_time: NaiveDateTime,
39 pub meta: HashMap<String, String>,
40 pub subaccounts: Vec<SubAccount>,
41}
42
43impl<'a> ToFwCall<'a> for CardChargeReq {
44 type ApiRequest = Self;
45
46 type ApiResponse = CardChargeRes;
47
48 fn get_call(self) -> FwCall<'a, Self::ApiRequest, Self::ApiResponse> {
49 FwCall::new(
50 Cow::Borrowed("/v3/charges?type=card_charge"),
51 reqwest::Method::POST,
52 Some(Payload::ToEncrypt(self)),
53 )
54 }
55}
56
57#[derive(Debug)]
58pub enum SubAccountChargeType {
59 Flat,
60 Percentage,
61 FlatSubAccount,
62}
63
64impl<'de> serde::Deserialize<'de> for SubAccountChargeType {
65 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66 where
67 D: serde::Deserializer<'de>,
68 {
69 struct SubAccountChargeTypeVisitor;
70
71 impl serde::de::Visitor<'_> for SubAccountChargeTypeVisitor {
72 type Value = SubAccountChargeType;
73
74 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
75 formatter.write_str("Expecting one of flat, percentage or flatsubaccount!")
76 }
77 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
78 where
79 E: serde::de::Error,
80 {
81 match v.to_ascii_lowercase().as_str() {
82 "flat" => Ok(SubAccountChargeType::Flat),
83 "percentage" => Ok(SubAccountChargeType::Percentage),
84 "flat_subaccount" => Ok(SubAccountChargeType::FlatSubAccount),
85 _ => Err(serde::de::Error::custom("Invalid Charge Type!")),
86 }
87 }
88
89 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
90 where
91 E: serde::de::Error,
92 {
93 match v.as_str() {
94 "flat" => Ok(SubAccountChargeType::Flat),
95 "percentage" => Ok(SubAccountChargeType::Percentage),
96 "flat_subaccount" => Ok(SubAccountChargeType::FlatSubAccount),
97 _ => Err(serde::de::Error::custom("Invalid Charge Type!")),
98 }
99 }
100 }
101 deserializer.deserialize_str(SubAccountChargeTypeVisitor)
102 }
103}
104
105impl serde::Serialize for SubAccountChargeType {
106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: serde::Serializer,
109 {
110 match self {
111 SubAccountChargeType::Flat => serializer.serialize_str("flat"),
112 SubAccountChargeType::Percentage => serializer.serialize_str("percentage"),
113 SubAccountChargeType::FlatSubAccount => serializer.serialize_str("flat_subaccount"),
114 }
115 }
116}
117
118#[derive(Debug, Serialize, Deserialize)]
119pub struct SubAccount {
120 pub id: String,
121 pub transaction_split_ratio: u8,
122 pub transaction_charge_type: SubAccountChargeType,
123 pub transaction_charge: u64,
124}
125
126#[derive(Serialize, Deserialize)]
127pub struct CardChargeRes {
128 pub status: String,
129 pub message: String,
130 pub data: ChargeResData,
131 pub meta: Meta,
132}
133
134#[derive(Serialize, Deserialize)]
135pub struct Meta {
136 pub authorization: Authorization,
137}
138
139#[derive(Serialize, Deserialize)]
140pub struct Authorization {
141 pub mode: String,
142 pub pin: i32,
143 pub city: String,
144 pub address: String,
145 pub state: String,
146 pub country: String,
147 pub zipcode: i32,
148 pub endpoint: String,
149}