Skip to main content

binance_sdk/fiat/rest_api/apis/
api.rs

1/*
2 * Fiat REST API
3 *
4 * Query Binance fiat deposit and withdrawal history.
5 *
6 * The version of the OpenAPI document: 1.0.0
7 *
8 *
9 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
10 * https://openapi-generator.tech
11 * Do not edit the class manually.
12 */
13
14#![allow(unused_imports)]
15use async_trait::async_trait;
16use derive_builder::Builder;
17use reqwest;
18use rust_decimal::prelude::*;
19use serde::{Deserialize, Serialize};
20use serde_json::{Value, json};
21use std::collections::BTreeMap;
22
23use crate::common::{
24    config::ConfigurationRestApi,
25    models::{ParamBuildError, RestApiResponse},
26    utils::send_request,
27};
28use crate::fiat::rest_api::models;
29
30const HAS_TIME_UNIT: bool = false;
31
32#[async_trait]
33pub trait Api: Send + Sync {
34    async fn deposit(
35        &self,
36        params: DepositParams,
37    ) -> anyhow::Result<RestApiResponse<models::DepositResponse>>;
38    async fn fiat_withdraw(
39        &self,
40        params: FiatWithdrawParams,
41    ) -> anyhow::Result<RestApiResponse<models::FiatWithdrawResponse>>;
42    async fn get_fiat_deposit_withdraw_history(
43        &self,
44        params: GetFiatDepositWithdrawHistoryParams,
45    ) -> anyhow::Result<RestApiResponse<models::GetFiatDepositWithdrawHistoryResponse>>;
46    async fn get_fiat_payments_history(
47        &self,
48        params: GetFiatPaymentsHistoryParams,
49    ) -> anyhow::Result<RestApiResponse<models::GetFiatPaymentsHistoryResponse>>;
50    async fn get_order_detail(
51        &self,
52        params: GetOrderDetailParams,
53    ) -> anyhow::Result<RestApiResponse<models::GetOrderDetailResponse>>;
54}
55
56#[derive(Debug, Clone)]
57pub struct ApiClient {
58    configuration: ConfigurationRestApi,
59}
60
61impl ApiClient {
62    pub fn new(configuration: ConfigurationRestApi) -> Self {
63        Self { configuration }
64    }
65}
66
67#[allow(non_camel_case_types)]
68#[derive(Debug, Clone, Serialize, Deserialize)]
69pub enum DepositApiPaymentMethodEnum {
70    #[serde(rename = "pix")]
71    Pix,
72}
73
74impl DepositApiPaymentMethodEnum {
75    #[must_use]
76    pub fn as_str(&self) -> &'static str {
77        match self {
78            Self::Pix => "pix",
79        }
80    }
81}
82
83impl std::str::FromStr for DepositApiPaymentMethodEnum {
84    type Err = Box<dyn std::error::Error + Send + Sync>;
85
86    fn from_str(s: &str) -> Result<Self, Self::Err> {
87        match s {
88            "pix" => Ok(Self::Pix),
89            other => Err(format!("invalid DepositApiPaymentMethodEnum: {}", other).into()),
90        }
91    }
92}
93
94#[allow(non_camel_case_types)]
95#[derive(Debug, Clone, Serialize, Deserialize)]
96pub enum FiatWithdrawApiPaymentMethodEnum {
97    #[serde(rename = "bank_transfer")]
98    BankTransfer,
99}
100
101impl FiatWithdrawApiPaymentMethodEnum {
102    #[must_use]
103    pub fn as_str(&self) -> &'static str {
104        match self {
105            Self::BankTransfer => "bank_transfer",
106        }
107    }
108}
109
110impl std::str::FromStr for FiatWithdrawApiPaymentMethodEnum {
111    type Err = Box<dyn std::error::Error + Send + Sync>;
112
113    fn from_str(s: &str) -> Result<Self, Self::Err> {
114        match s {
115            "bank_transfer" => Ok(Self::BankTransfer),
116            other => Err(format!("invalid FiatWithdrawApiPaymentMethodEnum: {}", other).into()),
117        }
118    }
119}
120
121/// Request parameters for the [`deposit`] operation.
122///
123/// This struct holds all of the inputs you can pass when calling
124/// [`deposit`](#method.deposit).
125#[derive(Clone, Debug, Builder, Deserialize)]
126#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
127pub struct DepositParams {
128    ///
129    /// The `currency` parameter.
130    ///
131    /// This field is **required.
132    #[builder(setter(into))]
133    #[serde(rename = "currency")]
134    pub currency: String,
135    /// payment method; current supported: pix
136    ///
137    /// This field is **required.
138    #[builder(setter(into))]
139    #[serde(rename = "apiPaymentMethod")]
140    pub api_payment_method: DepositApiPaymentMethodEnum,
141    /// deposit amount
142    ///
143    /// This field is **required.
144    #[builder(setter(into))]
145    #[serde(rename = "amount")]
146    pub amount: String,
147    /// Request validity window in milliseconds
148    ///
149    /// This field is **optional.
150    #[builder(setter(into), default)]
151    #[serde(rename = "recvWindow", default)]
152    pub recv_window: Option<i64>,
153    ///
154    /// The `ext` parameter.
155    ///
156    /// This field is **optional.
157    #[builder(setter(into), default)]
158    #[serde(rename = "ext", default)]
159    pub ext: Option<serde_json::Value>,
160}
161
162impl DepositParams {
163    /// Create a builder for [`deposit`].
164    ///
165    /// Required parameters:
166    ///
167    /// * `currency` — String
168    /// * `api_payment_method` — payment method; current supported: pix
169    /// * `amount` — deposit amount
170    ///
171    #[must_use]
172    pub fn builder(
173        currency: String,
174        api_payment_method: DepositApiPaymentMethodEnum,
175        amount: String,
176    ) -> DepositParamsBuilder {
177        DepositParamsBuilder::default()
178            .currency(currency)
179            .api_payment_method(api_payment_method)
180            .amount(amount)
181    }
182}
183/// Request parameters for the [`fiat_withdraw`] operation.
184///
185/// This struct holds all of the inputs you can pass when calling
186/// [`fiat_withdraw`](#method.fiat_withdraw).
187#[derive(Clone, Debug, Builder, Deserialize)]
188#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
189pub struct FiatWithdrawParams {
190    /// Fiat currency, such as BRL, ARS, MXN
191    ///
192    /// This field is **required.
193    #[builder(setter(into))]
194    #[serde(rename = "currency")]
195    pub currency: String,
196    /// payment method; current supported: `bank_transfer`
197    ///
198    /// This field is **required.
199    #[builder(setter(into))]
200    #[serde(rename = "apiPaymentMethod")]
201    pub api_payment_method: FiatWithdrawApiPaymentMethodEnum,
202    /// withdraw amount
203    ///
204    /// This field is **required.
205    #[builder(setter(into))]
206    #[serde(rename = "amount")]
207    pub amount: i64,
208    ///
209    /// The `account_info` parameter.
210    ///
211    /// This field is **required.
212    #[builder(setter(into))]
213    #[serde(rename = "accountInfo")]
214    pub account_info: models::FiatWithdrawRequestAccountInfo,
215    /// Request validity window in milliseconds
216    ///
217    /// This field is **optional.
218    #[builder(setter(into), default)]
219    #[serde(rename = "recvWindow", default)]
220    pub recv_window: Option<i64>,
221    ///
222    /// The `ext` parameter.
223    ///
224    /// This field is **optional.
225    #[builder(setter(into), default)]
226    #[serde(rename = "ext", default)]
227    pub ext: Option<serde_json::Value>,
228}
229
230impl FiatWithdrawParams {
231    /// Create a builder for [`fiat_withdraw`].
232    ///
233    /// Required parameters:
234    ///
235    /// * `currency` — Fiat currency, such as BRL, ARS, MXN
236    /// * `api_payment_method` — payment method; current supported: `bank_transfer`
237    /// * `amount` — withdraw amount
238    /// * `account_info` — `models::FiatWithdrawRequestAccountInfo`
239    ///
240    #[must_use]
241    pub fn builder(
242        currency: String,
243        api_payment_method: FiatWithdrawApiPaymentMethodEnum,
244        amount: i64,
245        account_info: models::FiatWithdrawRequestAccountInfo,
246    ) -> FiatWithdrawParamsBuilder {
247        FiatWithdrawParamsBuilder::default()
248            .currency(currency)
249            .api_payment_method(api_payment_method)
250            .amount(amount)
251            .account_info(account_info)
252    }
253}
254/// Request parameters for the [`get_fiat_deposit_withdraw_history`] operation.
255///
256/// This struct holds all of the inputs you can pass when calling
257/// [`get_fiat_deposit_withdraw_history`](#method.get_fiat_deposit_withdraw_history).
258#[derive(Clone, Debug, Builder, Deserialize)]
259#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
260pub struct GetFiatDepositWithdrawHistoryParams {
261    /// 0: deposit, 1: withdraw
262    ///
263    /// This field is **required.
264    #[builder(setter(into))]
265    #[serde(rename = "transactionType")]
266    pub transaction_type: String,
267    ///
268    /// The `begin_time` parameter.
269    ///
270    /// This field is **optional.
271    #[builder(setter(into), default)]
272    #[serde(rename = "beginTime", default)]
273    pub begin_time: Option<i64>,
274    ///
275    /// The `end_time` parameter.
276    ///
277    /// This field is **optional.
278    #[builder(setter(into), default)]
279    #[serde(rename = "endTime", default)]
280    pub end_time: Option<i64>,
281    ///
282    /// The `page` parameter.
283    ///
284    /// This field is **optional.
285    #[builder(setter(into), default)]
286    #[serde(rename = "page", default)]
287    pub page: Option<i64>,
288    ///
289    /// The `rows` parameter.
290    ///
291    /// This field is **optional.
292    #[builder(setter(into), default)]
293    #[serde(rename = "rows", default)]
294    pub rows: Option<i64>,
295    ///
296    /// The `recv_window` parameter.
297    ///
298    /// This field is **optional.
299    #[builder(setter(into), default)]
300    #[serde(rename = "recvWindow", default)]
301    pub recv_window: Option<i64>,
302}
303
304impl GetFiatDepositWithdrawHistoryParams {
305    /// Create a builder for [`get_fiat_deposit_withdraw_history`].
306    ///
307    /// Required parameters:
308    ///
309    /// * `transaction_type` — 0: deposit, 1: withdraw
310    ///
311    #[must_use]
312    pub fn builder(transaction_type: String) -> GetFiatDepositWithdrawHistoryParamsBuilder {
313        GetFiatDepositWithdrawHistoryParamsBuilder::default().transaction_type(transaction_type)
314    }
315}
316/// Request parameters for the [`get_fiat_payments_history`] operation.
317///
318/// This struct holds all of the inputs you can pass when calling
319/// [`get_fiat_payments_history`](#method.get_fiat_payments_history).
320#[derive(Clone, Debug, Builder, Deserialize)]
321#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
322pub struct GetFiatPaymentsHistoryParams {
323    /// 0: buy, 1: sell
324    ///
325    /// This field is **required.
326    #[builder(setter(into))]
327    #[serde(rename = "transactionType")]
328    pub transaction_type: String,
329    ///
330    /// The `begin_time` parameter.
331    ///
332    /// This field is **optional.
333    #[builder(setter(into), default)]
334    #[serde(rename = "beginTime", default)]
335    pub begin_time: Option<i64>,
336    ///
337    /// The `end_time` parameter.
338    ///
339    /// This field is **optional.
340    #[builder(setter(into), default)]
341    #[serde(rename = "endTime", default)]
342    pub end_time: Option<i64>,
343    ///
344    /// The `page` parameter.
345    ///
346    /// This field is **optional.
347    #[builder(setter(into), default)]
348    #[serde(rename = "page", default)]
349    pub page: Option<i64>,
350    ///
351    /// The `rows` parameter.
352    ///
353    /// This field is **optional.
354    #[builder(setter(into), default)]
355    #[serde(rename = "rows", default)]
356    pub rows: Option<i64>,
357    ///
358    /// The `recv_window` parameter.
359    ///
360    /// This field is **optional.
361    #[builder(setter(into), default)]
362    #[serde(rename = "recvWindow", default)]
363    pub recv_window: Option<i64>,
364}
365
366impl GetFiatPaymentsHistoryParams {
367    /// Create a builder for [`get_fiat_payments_history`].
368    ///
369    /// Required parameters:
370    ///
371    /// * `transaction_type` — 0: buy, 1: sell
372    ///
373    #[must_use]
374    pub fn builder(transaction_type: String) -> GetFiatPaymentsHistoryParamsBuilder {
375        GetFiatPaymentsHistoryParamsBuilder::default().transaction_type(transaction_type)
376    }
377}
378/// Request parameters for the [`get_order_detail`] operation.
379///
380/// This struct holds all of the inputs you can pass when calling
381/// [`get_order_detail`](#method.get_order_detail).
382#[derive(Clone, Debug, Builder, Deserialize)]
383#[builder(pattern = "owned", build_fn(error = "ParamBuildError"))]
384pub struct GetOrderDetailParams {
385    /// Order ID retrieved from the withdrawal API
386    ///
387    /// This field is **required.
388    #[builder(setter(into))]
389    #[serde(rename = "orderNo")]
390    pub order_no: String,
391    ///
392    /// The `recv_window` parameter.
393    ///
394    /// This field is **optional.
395    #[builder(setter(into), default)]
396    #[serde(rename = "recvWindow", default)]
397    pub recv_window: Option<i64>,
398}
399
400impl GetOrderDetailParams {
401    /// Create a builder for [`get_order_detail`].
402    ///
403    /// Required parameters:
404    ///
405    /// * `order_no` — Order ID retrieved from the withdrawal API
406    ///
407    #[must_use]
408    pub fn builder(order_no: String) -> GetOrderDetailParamsBuilder {
409        GetOrderDetailParamsBuilder::default().order_no(order_no)
410    }
411}
412
413#[async_trait]
414impl Api for ApiClient {
415    async fn deposit(
416        &self,
417        params: DepositParams,
418    ) -> anyhow::Result<RestApiResponse<models::DepositResponse>> {
419        let DepositParams {
420            currency,
421            api_payment_method,
422            amount,
423            recv_window,
424            ext,
425        } = params;
426
427        let mut query_params = BTreeMap::new();
428        let mut body_params = BTreeMap::new();
429
430        if let Some(rw) = recv_window {
431            query_params.insert("recvWindow".to_string(), json!(rw));
432        }
433
434        body_params.insert("currency".to_string(), json!(currency));
435
436        body_params.insert("apiPaymentMethod".to_string(), json!(api_payment_method));
437
438        body_params.insert("amount".to_string(), json!(amount));
439
440        if let Some(rw) = ext {
441            body_params.insert("ext".to_string(), json!(rw));
442        }
443
444        send_request::<models::DepositResponse>(
445            &self.configuration,
446            "/sapi/v1/fiat/deposit",
447            reqwest::Method::POST,
448            query_params,
449            body_params,
450            if HAS_TIME_UNIT {
451                self.configuration.time_unit
452            } else {
453                None
454            },
455            true,
456        )
457        .await
458    }
459
460    async fn fiat_withdraw(
461        &self,
462        params: FiatWithdrawParams,
463    ) -> anyhow::Result<RestApiResponse<models::FiatWithdrawResponse>> {
464        let FiatWithdrawParams {
465            currency,
466            api_payment_method,
467            amount,
468            account_info,
469            recv_window,
470            ext,
471        } = params;
472
473        let mut query_params = BTreeMap::new();
474        let mut body_params = BTreeMap::new();
475
476        if let Some(rw) = recv_window {
477            query_params.insert("recvWindow".to_string(), json!(rw));
478        }
479
480        body_params.insert("currency".to_string(), json!(currency));
481
482        body_params.insert("apiPaymentMethod".to_string(), json!(api_payment_method));
483
484        body_params.insert("amount".to_string(), json!(amount));
485
486        body_params.insert("accountInfo".to_string(), json!(account_info));
487
488        if let Some(rw) = ext {
489            body_params.insert("ext".to_string(), json!(rw));
490        }
491
492        send_request::<models::FiatWithdrawResponse>(
493            &self.configuration,
494            "/sapi/v2/fiat/withdraw",
495            reqwest::Method::POST,
496            query_params,
497            body_params,
498            if HAS_TIME_UNIT {
499                self.configuration.time_unit
500            } else {
501                None
502            },
503            true,
504        )
505        .await
506    }
507
508    async fn get_fiat_deposit_withdraw_history(
509        &self,
510        params: GetFiatDepositWithdrawHistoryParams,
511    ) -> anyhow::Result<RestApiResponse<models::GetFiatDepositWithdrawHistoryResponse>> {
512        let GetFiatDepositWithdrawHistoryParams {
513            transaction_type,
514            begin_time,
515            end_time,
516            page,
517            rows,
518            recv_window,
519        } = params;
520
521        let mut query_params = BTreeMap::new();
522        let body_params = BTreeMap::new();
523
524        query_params.insert("transactionType".to_string(), json!(transaction_type));
525
526        if let Some(rw) = begin_time {
527            query_params.insert("beginTime".to_string(), json!(rw));
528        }
529
530        if let Some(rw) = end_time {
531            query_params.insert("endTime".to_string(), json!(rw));
532        }
533
534        if let Some(rw) = page {
535            query_params.insert("page".to_string(), json!(rw));
536        }
537
538        if let Some(rw) = rows {
539            query_params.insert("rows".to_string(), json!(rw));
540        }
541
542        if let Some(rw) = recv_window {
543            query_params.insert("recvWindow".to_string(), json!(rw));
544        }
545
546        send_request::<models::GetFiatDepositWithdrawHistoryResponse>(
547            &self.configuration,
548            "/sapi/v1/fiat/orders",
549            reqwest::Method::GET,
550            query_params,
551            body_params,
552            if HAS_TIME_UNIT {
553                self.configuration.time_unit
554            } else {
555                None
556            },
557            true,
558        )
559        .await
560    }
561
562    async fn get_fiat_payments_history(
563        &self,
564        params: GetFiatPaymentsHistoryParams,
565    ) -> anyhow::Result<RestApiResponse<models::GetFiatPaymentsHistoryResponse>> {
566        let GetFiatPaymentsHistoryParams {
567            transaction_type,
568            begin_time,
569            end_time,
570            page,
571            rows,
572            recv_window,
573        } = params;
574
575        let mut query_params = BTreeMap::new();
576        let body_params = BTreeMap::new();
577
578        query_params.insert("transactionType".to_string(), json!(transaction_type));
579
580        if let Some(rw) = begin_time {
581            query_params.insert("beginTime".to_string(), json!(rw));
582        }
583
584        if let Some(rw) = end_time {
585            query_params.insert("endTime".to_string(), json!(rw));
586        }
587
588        if let Some(rw) = page {
589            query_params.insert("page".to_string(), json!(rw));
590        }
591
592        if let Some(rw) = rows {
593            query_params.insert("rows".to_string(), json!(rw));
594        }
595
596        if let Some(rw) = recv_window {
597            query_params.insert("recvWindow".to_string(), json!(rw));
598        }
599
600        send_request::<models::GetFiatPaymentsHistoryResponse>(
601            &self.configuration,
602            "/sapi/v1/fiat/payments",
603            reqwest::Method::GET,
604            query_params,
605            body_params,
606            if HAS_TIME_UNIT {
607                self.configuration.time_unit
608            } else {
609                None
610            },
611            true,
612        )
613        .await
614    }
615
616    async fn get_order_detail(
617        &self,
618        params: GetOrderDetailParams,
619    ) -> anyhow::Result<RestApiResponse<models::GetOrderDetailResponse>> {
620        let GetOrderDetailParams {
621            order_no,
622            recv_window,
623        } = params;
624
625        let mut query_params = BTreeMap::new();
626        let body_params = BTreeMap::new();
627
628        query_params.insert("orderNo".to_string(), json!(order_no));
629
630        if let Some(rw) = recv_window {
631            query_params.insert("recvWindow".to_string(), json!(rw));
632        }
633
634        send_request::<models::GetOrderDetailResponse>(
635            &self.configuration,
636            "/sapi/v1/fiat/get-order-detail",
637            reqwest::Method::GET,
638            query_params,
639            body_params,
640            if HAS_TIME_UNIT {
641                self.configuration.time_unit
642            } else {
643                None
644            },
645            true,
646        )
647        .await
648    }
649}
650
651#[cfg(all(test, feature = "fiat"))]
652mod tests {
653    use super::*;
654    use crate::TOKIO_SHARED_RT;
655    use crate::{errors::ConnectorError, models::DataFuture, models::RestApiRateLimit};
656    use async_trait::async_trait;
657    use std::collections::HashMap;
658
659    struct DummyRestApiResponse<T> {
660        inner: Box<dyn FnOnce() -> DataFuture<Result<T, ConnectorError>> + Send + Sync>,
661        status: u16,
662        headers: HashMap<String, String>,
663        rate_limits: Option<Vec<RestApiRateLimit>>,
664    }
665
666    impl<T> From<DummyRestApiResponse<T>> for RestApiResponse<T> {
667        fn from(dummy: DummyRestApiResponse<T>) -> Self {
668            Self {
669                data_fn: dummy.inner,
670                status: dummy.status,
671                headers: dummy.headers,
672                rate_limits: dummy.rate_limits,
673            }
674        }
675    }
676
677    struct MockApiClient {
678        force_error: bool,
679    }
680
681    #[async_trait]
682    impl Api for MockApiClient {
683        async fn deposit(
684            &self,
685            _params: DepositParams,
686        ) -> anyhow::Result<RestApiResponse<models::DepositResponse>> {
687            if self.force_error {
688                return Err(ConnectorError::ConnectorClientError {
689                    msg: "ResponseError".to_string(),
690                    code: None,
691                }
692                .into());
693            }
694
695            let resp_json: Value = serde_json::from_str(
696                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
697            )
698            .unwrap_or_else(|_| serde_json::json!({}));
699            let dummy_response: models::DepositResponse = serde_json::from_value(resp_json.clone())
700                .expect("should parse into models::DepositResponse");
701
702            let dummy = DummyRestApiResponse {
703                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
704                status: 200,
705                headers: HashMap::new(),
706                rate_limits: None,
707            };
708
709            Ok(dummy.into())
710        }
711
712        async fn fiat_withdraw(
713            &self,
714            _params: FiatWithdrawParams,
715        ) -> anyhow::Result<RestApiResponse<models::FiatWithdrawResponse>> {
716            if self.force_error {
717                return Err(ConnectorError::ConnectorClientError {
718                    msg: "ResponseError".to_string(),
719                    code: None,
720                }
721                .into());
722            }
723
724            let resp_json: Value = serde_json::from_str(
725                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
726            )
727            .unwrap_or_else(|_| serde_json::json!({}));
728            let dummy_response: models::FiatWithdrawResponse =
729                serde_json::from_value(resp_json.clone())
730                    .expect("should parse into models::FiatWithdrawResponse");
731
732            let dummy = DummyRestApiResponse {
733                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
734                status: 200,
735                headers: HashMap::new(),
736                rate_limits: None,
737            };
738
739            Ok(dummy.into())
740        }
741
742        async fn get_fiat_deposit_withdraw_history(
743            &self,
744            _params: GetFiatDepositWithdrawHistoryParams,
745        ) -> anyhow::Result<RestApiResponse<models::GetFiatDepositWithdrawHistoryResponse>>
746        {
747            if self.force_error {
748                return Err(ConnectorError::ConnectorClientError {
749                    msg: "ResponseError".to_string(),
750                    code: None,
751                }
752                .into());
753            }
754
755            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"7d76d611-0568-4f43-afb6-24cac7767365","fiatCurrency":"BRL","indicatedAmount":"10.00","amount":"10.00","totalFee":"0.00","method":"BankAccount","status":"Expired","createTime":1626144956000,"updateTime":1626400907000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
756            let dummy_response: models::GetFiatDepositWithdrawHistoryResponse =
757                serde_json::from_value(resp_json.clone())
758                    .expect("should parse into models::GetFiatDepositWithdrawHistoryResponse");
759
760            let dummy = DummyRestApiResponse {
761                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
762                status: 200,
763                headers: HashMap::new(),
764                rate_limits: None,
765            };
766
767            Ok(dummy.into())
768        }
769
770        async fn get_fiat_payments_history(
771            &self,
772            _params: GetFiatPaymentsHistoryParams,
773        ) -> anyhow::Result<RestApiResponse<models::GetFiatPaymentsHistoryResponse>> {
774            if self.force_error {
775                return Err(ConnectorError::ConnectorClientError {
776                    msg: "ResponseError".to_string(),
777                    code: None,
778                }
779                .into());
780            }
781
782            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"353fca443f06466db0c4dc89f94f027a","sourceAmount":"20.0","fiatCurrency":"EUR","obtainAmount":"4.462","cryptoCurrency":"LUNA","totalFee":"0.2","price":"4.437472","status":"Failed","paymentMethod":"Credit Card","createTime":1624529919000,"updateTime":1624529919000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
783            let dummy_response: models::GetFiatPaymentsHistoryResponse =
784                serde_json::from_value(resp_json.clone())
785                    .expect("should parse into models::GetFiatPaymentsHistoryResponse");
786
787            let dummy = DummyRestApiResponse {
788                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
789                status: 200,
790                headers: HashMap::new(),
791                rate_limits: None,
792            };
793
794            Ok(dummy.into())
795        }
796
797        async fn get_order_detail(
798            &self,
799            _params: GetOrderDetailParams,
800        ) -> anyhow::Result<RestApiResponse<models::GetOrderDetailResponse>> {
801            if self.force_error {
802                return Err(ConnectorError::ConnectorClientError {
803                    msg: "ResponseError".to_string(),
804                    code: None,
805                }
806                .into());
807            }
808
809            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":{"orderId":"036752*678","orderStatus":"ORDER_INITIAL","amount":"4.33","fee":"0.43","fiatCurrency":"***","errorCode":"","errorMessage":"","ext":{}}}"#).unwrap_or_else(|_| serde_json::json!({}));
810            let dummy_response: models::GetOrderDetailResponse =
811                serde_json::from_value(resp_json.clone())
812                    .expect("should parse into models::GetOrderDetailResponse");
813
814            let dummy = DummyRestApiResponse {
815                inner: Box::new(move || Box::pin(async move { Ok(dummy_response) })),
816                status: 200,
817                headers: HashMap::new(),
818                rate_limits: None,
819            };
820
821            Ok(dummy.into())
822        }
823    }
824
825    #[test]
826    fn deposit_required_params_success() {
827        TOKIO_SHARED_RT.block_on(async {
828            let client = MockApiClient { force_error: false };
829
830            let params = DepositParams::builder(
831                "currency_example".to_string(),
832                DepositApiPaymentMethodEnum::Pix,
833                "amount_example".to_string(),
834            )
835            .build()
836            .unwrap();
837
838            let resp_json: Value = serde_json::from_str(
839                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
840            )
841            .unwrap_or_else(|_| serde_json::json!({}));
842            let expected_response: models::DepositResponse =
843                serde_json::from_value(resp_json.clone())
844                    .expect("should parse into models::DepositResponse");
845
846            let resp = client.deposit(params).await.expect("Expected a response");
847            let data_future = resp.data();
848            let actual_response = data_future.await.unwrap();
849            assert_eq!(actual_response, expected_response);
850        });
851    }
852
853    #[test]
854    fn deposit_optional_params_success() {
855        TOKIO_SHARED_RT.block_on(async {
856            let client = MockApiClient { force_error: false };
857
858            let params = DepositParams::builder(
859                "currency_example".to_string(),
860                DepositApiPaymentMethodEnum::Pix,
861                "amount_example".to_string(),
862            )
863            .recv_window(5000)
864            .ext(serde_json::Value::Object(Default::default()))
865            .build()
866            .unwrap();
867
868            let resp_json: Value = serde_json::from_str(
869                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
870            )
871            .unwrap_or_else(|_| serde_json::json!({}));
872            let expected_response: models::DepositResponse =
873                serde_json::from_value(resp_json.clone())
874                    .expect("should parse into models::DepositResponse");
875
876            let resp = client.deposit(params).await.expect("Expected a response");
877            let data_future = resp.data();
878            let actual_response = data_future.await.unwrap();
879            assert_eq!(actual_response, expected_response);
880        });
881    }
882
883    #[test]
884    fn deposit_response_error() {
885        TOKIO_SHARED_RT.block_on(async {
886            let client = MockApiClient { force_error: true };
887
888            let params = DepositParams::builder(
889                "currency_example".to_string(),
890                DepositApiPaymentMethodEnum::Pix,
891                "amount_example".to_string(),
892            )
893            .build()
894            .unwrap();
895
896            match client.deposit(params).await {
897                Ok(_) => panic!("Expected an error"),
898                Err(err) => {
899                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
900                }
901            }
902        });
903    }
904
905    #[test]
906    fn fiat_withdraw_required_params_success() {
907        TOKIO_SHARED_RT.block_on(async {
908            let client = MockApiClient { force_error: false };
909
910            let params = FiatWithdrawParams::builder(
911                "currency_example".to_string(),
912                FiatWithdrawApiPaymentMethodEnum::BankTransfer,
913                789,
914                models::FiatWithdrawRequestAccountInfo::default(),
915            )
916            .build()
917            .unwrap();
918
919            let resp_json: Value = serde_json::from_str(
920                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
921            )
922            .unwrap_or_else(|_| serde_json::json!({}));
923            let expected_response: models::FiatWithdrawResponse =
924                serde_json::from_value(resp_json.clone())
925                    .expect("should parse into models::FiatWithdrawResponse");
926
927            let resp = client
928                .fiat_withdraw(params)
929                .await
930                .expect("Expected a response");
931            let data_future = resp.data();
932            let actual_response = data_future.await.unwrap();
933            assert_eq!(actual_response, expected_response);
934        });
935    }
936
937    #[test]
938    fn fiat_withdraw_optional_params_success() {
939        TOKIO_SHARED_RT.block_on(async {
940            let client = MockApiClient { force_error: false };
941
942            let params = FiatWithdrawParams::builder(
943                "currency_example".to_string(),
944                FiatWithdrawApiPaymentMethodEnum::BankTransfer,
945                789,
946                models::FiatWithdrawRequestAccountInfo::default(),
947            )
948            .recv_window(5000)
949            .ext(serde_json::Value::Object(Default::default()))
950            .build()
951            .unwrap();
952
953            let resp_json: Value = serde_json::from_str(
954                r#"{"code":"000000","message":"success","data":{"orderId":"04595xxxxxxxxx37"}}"#,
955            )
956            .unwrap_or_else(|_| serde_json::json!({}));
957            let expected_response: models::FiatWithdrawResponse =
958                serde_json::from_value(resp_json.clone())
959                    .expect("should parse into models::FiatWithdrawResponse");
960
961            let resp = client
962                .fiat_withdraw(params)
963                .await
964                .expect("Expected a response");
965            let data_future = resp.data();
966            let actual_response = data_future.await.unwrap();
967            assert_eq!(actual_response, expected_response);
968        });
969    }
970
971    #[test]
972    fn fiat_withdraw_response_error() {
973        TOKIO_SHARED_RT.block_on(async {
974            let client = MockApiClient { force_error: true };
975
976            let params = FiatWithdrawParams::builder(
977                "currency_example".to_string(),
978                FiatWithdrawApiPaymentMethodEnum::BankTransfer,
979                789,
980                models::FiatWithdrawRequestAccountInfo::default(),
981            )
982            .build()
983            .unwrap();
984
985            match client.fiat_withdraw(params).await {
986                Ok(_) => panic!("Expected an error"),
987                Err(err) => {
988                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
989                }
990            }
991        });
992    }
993
994    #[test]
995    fn get_fiat_deposit_withdraw_history_required_params_success() {
996        TOKIO_SHARED_RT.block_on(async {
997            let client = MockApiClient { force_error: false };
998
999            let params = GetFiatDepositWithdrawHistoryParams::builder("0".to_string(),).build().unwrap();
1000
1001            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"7d76d611-0568-4f43-afb6-24cac7767365","fiatCurrency":"BRL","indicatedAmount":"10.00","amount":"10.00","totalFee":"0.00","method":"BankAccount","status":"Expired","createTime":1626144956000,"updateTime":1626400907000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
1002            let expected_response : models::GetFiatDepositWithdrawHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFiatDepositWithdrawHistoryResponse");
1003
1004            let resp = client.get_fiat_deposit_withdraw_history(params).await.expect("Expected a response");
1005            let data_future = resp.data();
1006            let actual_response = data_future.await.unwrap();
1007            assert_eq!(actual_response, expected_response);
1008        });
1009    }
1010
1011    #[test]
1012    fn get_fiat_deposit_withdraw_history_optional_params_success() {
1013        TOKIO_SHARED_RT.block_on(async {
1014            let client = MockApiClient { force_error: false };
1015
1016            let params = GetFiatDepositWithdrawHistoryParams::builder("0".to_string(),).begin_time(1641782889000).end_time(1641782889000).page(1).rows(100).recv_window(5000).build().unwrap();
1017
1018            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"7d76d611-0568-4f43-afb6-24cac7767365","fiatCurrency":"BRL","indicatedAmount":"10.00","amount":"10.00","totalFee":"0.00","method":"BankAccount","status":"Expired","createTime":1626144956000,"updateTime":1626400907000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
1019            let expected_response : models::GetFiatDepositWithdrawHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFiatDepositWithdrawHistoryResponse");
1020
1021            let resp = client.get_fiat_deposit_withdraw_history(params).await.expect("Expected a response");
1022            let data_future = resp.data();
1023            let actual_response = data_future.await.unwrap();
1024            assert_eq!(actual_response, expected_response);
1025        });
1026    }
1027
1028    #[test]
1029    fn get_fiat_deposit_withdraw_history_response_error() {
1030        TOKIO_SHARED_RT.block_on(async {
1031            let client = MockApiClient { force_error: true };
1032
1033            let params = GetFiatDepositWithdrawHistoryParams::builder("0".to_string())
1034                .build()
1035                .unwrap();
1036
1037            match client.get_fiat_deposit_withdraw_history(params).await {
1038                Ok(_) => panic!("Expected an error"),
1039                Err(err) => {
1040                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1041                }
1042            }
1043        });
1044    }
1045
1046    #[test]
1047    fn get_fiat_payments_history_required_params_success() {
1048        TOKIO_SHARED_RT.block_on(async {
1049            let client = MockApiClient { force_error: false };
1050
1051            let params = GetFiatPaymentsHistoryParams::builder("0".to_string(),).build().unwrap();
1052
1053            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"353fca443f06466db0c4dc89f94f027a","sourceAmount":"20.0","fiatCurrency":"EUR","obtainAmount":"4.462","cryptoCurrency":"LUNA","totalFee":"0.2","price":"4.437472","status":"Failed","paymentMethod":"Credit Card","createTime":1624529919000,"updateTime":1624529919000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
1054            let expected_response : models::GetFiatPaymentsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFiatPaymentsHistoryResponse");
1055
1056            let resp = client.get_fiat_payments_history(params).await.expect("Expected a response");
1057            let data_future = resp.data();
1058            let actual_response = data_future.await.unwrap();
1059            assert_eq!(actual_response, expected_response);
1060        });
1061    }
1062
1063    #[test]
1064    fn get_fiat_payments_history_optional_params_success() {
1065        TOKIO_SHARED_RT.block_on(async {
1066            let client = MockApiClient { force_error: false };
1067
1068            let params = GetFiatPaymentsHistoryParams::builder("0".to_string(),).begin_time(1641782889000).end_time(1641782889000).page(1).rows(100).recv_window(5000).build().unwrap();
1069
1070            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":[{"orderNo":"353fca443f06466db0c4dc89f94f027a","sourceAmount":"20.0","fiatCurrency":"EUR","obtainAmount":"4.462","cryptoCurrency":"LUNA","totalFee":"0.2","price":"4.437472","status":"Failed","paymentMethod":"Credit Card","createTime":1624529919000,"updateTime":1624529919000}],"total":1,"success":true}"#).unwrap_or_else(|_| serde_json::json!({}));
1071            let expected_response : models::GetFiatPaymentsHistoryResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetFiatPaymentsHistoryResponse");
1072
1073            let resp = client.get_fiat_payments_history(params).await.expect("Expected a response");
1074            let data_future = resp.data();
1075            let actual_response = data_future.await.unwrap();
1076            assert_eq!(actual_response, expected_response);
1077        });
1078    }
1079
1080    #[test]
1081    fn get_fiat_payments_history_response_error() {
1082        TOKIO_SHARED_RT.block_on(async {
1083            let client = MockApiClient { force_error: true };
1084
1085            let params = GetFiatPaymentsHistoryParams::builder("0".to_string())
1086                .build()
1087                .unwrap();
1088
1089            match client.get_fiat_payments_history(params).await {
1090                Ok(_) => panic!("Expected an error"),
1091                Err(err) => {
1092                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1093                }
1094            }
1095        });
1096    }
1097
1098    #[test]
1099    fn get_order_detail_required_params_success() {
1100        TOKIO_SHARED_RT.block_on(async {
1101            let client = MockApiClient { force_error: false };
1102
1103            let params = GetOrderDetailParams::builder("036752*678".to_string(),).build().unwrap();
1104
1105            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":{"orderId":"036752*678","orderStatus":"ORDER_INITIAL","amount":"4.33","fee":"0.43","fiatCurrency":"***","errorCode":"","errorMessage":"","ext":{}}}"#).unwrap_or_else(|_| serde_json::json!({}));
1106            let expected_response : models::GetOrderDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderDetailResponse");
1107
1108            let resp = client.get_order_detail(params).await.expect("Expected a response");
1109            let data_future = resp.data();
1110            let actual_response = data_future.await.unwrap();
1111            assert_eq!(actual_response, expected_response);
1112        });
1113    }
1114
1115    #[test]
1116    fn get_order_detail_optional_params_success() {
1117        TOKIO_SHARED_RT.block_on(async {
1118            let client = MockApiClient { force_error: false };
1119
1120            let params = GetOrderDetailParams::builder("036752*678".to_string(),).recv_window(5000).build().unwrap();
1121
1122            let resp_json: Value = serde_json::from_str(r#"{"code":"000000","message":"success","data":{"orderId":"036752*678","orderStatus":"ORDER_INITIAL","amount":"4.33","fee":"0.43","fiatCurrency":"***","errorCode":"","errorMessage":"","ext":{}}}"#).unwrap_or_else(|_| serde_json::json!({}));
1123            let expected_response : models::GetOrderDetailResponse = serde_json::from_value(resp_json.clone()).expect("should parse into models::GetOrderDetailResponse");
1124
1125            let resp = client.get_order_detail(params).await.expect("Expected a response");
1126            let data_future = resp.data();
1127            let actual_response = data_future.await.unwrap();
1128            assert_eq!(actual_response, expected_response);
1129        });
1130    }
1131
1132    #[test]
1133    fn get_order_detail_response_error() {
1134        TOKIO_SHARED_RT.block_on(async {
1135            let client = MockApiClient { force_error: true };
1136
1137            let params = GetOrderDetailParams::builder("036752*678".to_string())
1138                .build()
1139                .unwrap();
1140
1141            match client.get_order_detail(params).await {
1142                Ok(_) => panic!("Expected an error"),
1143                Err(err) => {
1144                    assert_eq!(err.to_string(), "Connector client error: ResponseError");
1145                }
1146            }
1147        });
1148    }
1149}