lb_rs/service/
billing.rs

1use crate::Lb;
2use crate::io::network::ApiError;
3use crate::model::api::{
4    CancelSubscriptionError, CancelSubscriptionRequest, GetSubscriptionInfoRequest,
5    StripeAccountTier, SubscriptionInfo, UpgradeAccountAppStoreError,
6    UpgradeAccountAppStoreRequest, UpgradeAccountGooglePlayError, UpgradeAccountGooglePlayRequest,
7    UpgradeAccountStripeError, UpgradeAccountStripeRequest,
8};
9use crate::model::errors::{LbErrKind, LbResult, core_err_unexpected};
10
11// todo: when core is responsible for syncing, these should probably trigger syncs and status updates
12impl Lb {
13    #[instrument(level = "debug", skip(self, account_tier), err(Debug))]
14    pub async fn upgrade_account_stripe(&self, account_tier: StripeAccountTier) -> LbResult<()> {
15        let account = self.get_account()?;
16
17        self.client
18            .request(account, UpgradeAccountStripeRequest { account_tier })
19            .await
20            .map_err(|err| match err {
21                ApiError::Endpoint(err) => match err {
22                    UpgradeAccountStripeError::OldCardDoesNotExist => {
23                        LbErrKind::OldCardDoesNotExist
24                    }
25                    UpgradeAccountStripeError::AlreadyPremium => LbErrKind::AlreadyPremium,
26                    UpgradeAccountStripeError::InvalidCardNumber => LbErrKind::CardInvalidNumber,
27                    UpgradeAccountStripeError::InvalidCardExpYear => LbErrKind::CardInvalidExpYear,
28                    UpgradeAccountStripeError::InvalidCardExpMonth => {
29                        LbErrKind::CardInvalidExpMonth
30                    }
31                    UpgradeAccountStripeError::InvalidCardCvc => LbErrKind::CardInvalidCvc,
32                    UpgradeAccountStripeError::CardDecline => LbErrKind::CardDecline,
33                    UpgradeAccountStripeError::InsufficientFunds => {
34                        LbErrKind::CardInsufficientFunds
35                    }
36                    UpgradeAccountStripeError::TryAgain => LbErrKind::TryAgain,
37                    UpgradeAccountStripeError::CardNotSupported => LbErrKind::CardNotSupported,
38                    UpgradeAccountStripeError::ExpiredCard => LbErrKind::CardExpired,
39                    UpgradeAccountStripeError::ExistingRequestPending => {
40                        LbErrKind::ExistingRequestPending
41                    }
42                    UpgradeAccountStripeError::UserNotFound => LbErrKind::AccountNonexistent,
43                },
44                ApiError::SendFailed(_) => LbErrKind::ServerUnreachable,
45                ApiError::ClientUpdateRequired => LbErrKind::ClientUpdateRequired,
46                _ => core_err_unexpected(err),
47            })?;
48
49        Ok(())
50    }
51
52    #[instrument(level = "debug", skip(self), err(Debug))]
53    pub async fn upgrade_account_google_play(
54        &self, purchase_token: &str, account_id: &str,
55    ) -> LbResult<()> {
56        let account = self.get_account()?;
57
58        self.client
59            .request(
60                account,
61                UpgradeAccountGooglePlayRequest {
62                    purchase_token: purchase_token.to_string(),
63                    account_id: account_id.to_string(),
64                },
65            )
66            .await
67            .map_err(|err| match err {
68                ApiError::Endpoint(err) => match err {
69                    UpgradeAccountGooglePlayError::AlreadyPremium => LbErrKind::AlreadyPremium,
70                    UpgradeAccountGooglePlayError::InvalidPurchaseToken => {
71                        LbErrKind::InvalidPurchaseToken
72                    }
73                    UpgradeAccountGooglePlayError::ExistingRequestPending => {
74                        LbErrKind::ExistingRequestPending
75                    }
76                    UpgradeAccountGooglePlayError::UserNotFound => core_err_unexpected(err),
77                },
78                ApiError::SendFailed(_) => LbErrKind::ServerUnreachable,
79                ApiError::ClientUpdateRequired => LbErrKind::ClientUpdateRequired,
80                _ => core_err_unexpected(err),
81            })?;
82
83        Ok(())
84    }
85
86    #[instrument(level = "debug", skip(self), err(Debug))]
87    pub async fn upgrade_account_app_store(
88        &self, original_transaction_id: String, app_account_token: String,
89    ) -> LbResult<()> {
90        let account = self.get_account()?;
91
92        self.client
93            .request(
94                account,
95                UpgradeAccountAppStoreRequest { original_transaction_id, app_account_token },
96            )
97            .await
98            .map_err(|err| match err {
99                ApiError::Endpoint(err) => match err {
100                    UpgradeAccountAppStoreError::AlreadyPremium => LbErrKind::AlreadyPremium,
101                    UpgradeAccountAppStoreError::InvalidAuthDetails => {
102                        LbErrKind::InvalidAuthDetails
103                    }
104                    UpgradeAccountAppStoreError::ExistingRequestPending => {
105                        LbErrKind::ExistingRequestPending
106                    }
107                    UpgradeAccountAppStoreError::AppStoreAccountAlreadyLinked => {
108                        LbErrKind::AppStoreAccountAlreadyLinked
109                    }
110                    UpgradeAccountAppStoreError::UserNotFound => core_err_unexpected(err),
111                },
112                ApiError::SendFailed(_) => LbErrKind::ServerUnreachable,
113                ApiError::ClientUpdateRequired => LbErrKind::ClientUpdateRequired,
114                _ => core_err_unexpected(err),
115            })?;
116
117        Ok(())
118    }
119
120    #[instrument(level = "debug", skip(self), err(Debug))]
121    pub async fn cancel_subscription(&self) -> LbResult<()> {
122        let account = self.get_account()?;
123
124        self.client
125            .request(account, CancelSubscriptionRequest {})
126            .await
127            .map_err(|err| match err {
128                ApiError::Endpoint(CancelSubscriptionError::NotPremium) => LbErrKind::NotPremium,
129                ApiError::Endpoint(CancelSubscriptionError::AlreadyCanceled) => {
130                    LbErrKind::AlreadyCanceled
131                }
132                ApiError::Endpoint(CancelSubscriptionError::UsageIsOverFreeTierDataCap) => {
133                    LbErrKind::UsageIsOverFreeTierDataCap
134                }
135                ApiError::Endpoint(CancelSubscriptionError::ExistingRequestPending) => {
136                    LbErrKind::ExistingRequestPending
137                }
138                ApiError::Endpoint(CancelSubscriptionError::CannotCancelForAppStore) => {
139                    LbErrKind::CannotCancelSubscriptionForAppStore
140                }
141                ApiError::SendFailed(_) => LbErrKind::ServerUnreachable,
142                ApiError::ClientUpdateRequired => LbErrKind::ClientUpdateRequired,
143                _ => core_err_unexpected(err),
144            })?;
145
146        Ok(())
147    }
148
149    #[instrument(level = "debug", skip(self), err(Debug))]
150    pub async fn get_subscription_info(&self) -> LbResult<Option<SubscriptionInfo>> {
151        let account = self.get_account()?;
152
153        Ok(self
154            .client
155            .request(account, GetSubscriptionInfoRequest {})
156            .await
157            .map_err(|err| match err {
158                ApiError::SendFailed(_) => LbErrKind::ServerUnreachable,
159                ApiError::ClientUpdateRequired => LbErrKind::ClientUpdateRequired,
160                _ => core_err_unexpected(err),
161            })?
162            .subscription_info)
163    }
164}