1#[cfg(test)]
2mod fake_stripe_client;
3mod real_stripe_client;
4
5use std::collections::HashMap;
6use std::sync::Arc;
7
8use anyhow::Result;
9use async_trait::async_trait;
10
11#[cfg(test)]
12pub use fake_stripe_client::*;
13pub use real_stripe_client::*;
14use serde::{Deserialize, Serialize};
15
16#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Serialize)]
17pub struct StripeCustomerId(pub Arc<str>);
18
19#[derive(Debug, Clone)]
20pub struct StripeCustomer {
21 pub id: StripeCustomerId,
22 pub email: Option<String>,
23}
24
25#[derive(Debug)]
26pub struct CreateCustomerParams<'a> {
27 pub email: Option<&'a str>,
28}
29
30#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
31pub struct StripeSubscriptionId(pub Arc<str>);
32
33#[derive(Debug, PartialEq, Clone)]
34pub struct StripeSubscription {
35 pub id: StripeSubscriptionId,
36 pub customer: StripeCustomerId,
37 // TODO: Create our own version of this enum.
38 pub status: stripe::SubscriptionStatus,
39 pub current_period_end: i64,
40 pub current_period_start: i64,
41 pub items: Vec<StripeSubscriptionItem>,
42}
43
44#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
45pub struct StripeSubscriptionItemId(pub Arc<str>);
46
47#[derive(Debug, PartialEq, Clone)]
48pub struct StripeSubscriptionItem {
49 pub id: StripeSubscriptionItemId,
50 pub price: Option<StripePrice>,
51}
52
53#[derive(Debug)]
54pub struct StripeCreateSubscriptionParams {
55 pub customer: StripeCustomerId,
56 pub items: Vec<StripeCreateSubscriptionItems>,
57}
58
59#[derive(Debug)]
60pub struct StripeCreateSubscriptionItems {
61 pub price: Option<StripePriceId>,
62 pub quantity: Option<u64>,
63}
64
65#[derive(Debug, Clone)]
66pub struct UpdateSubscriptionParams {
67 pub items: Option<Vec<UpdateSubscriptionItems>>,
68 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
69}
70
71#[derive(Debug, PartialEq, Clone)]
72pub struct UpdateSubscriptionItems {
73 pub price: Option<StripePriceId>,
74}
75
76#[derive(Debug, PartialEq, Clone)]
77pub struct StripeSubscriptionTrialSettings {
78 pub end_behavior: StripeSubscriptionTrialSettingsEndBehavior,
79}
80
81#[derive(Debug, PartialEq, Clone)]
82pub struct StripeSubscriptionTrialSettingsEndBehavior {
83 pub missing_payment_method: StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod,
84}
85
86#[derive(Debug, PartialEq, Eq, Clone, Copy)]
87pub enum StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod {
88 Cancel,
89 CreateInvoice,
90 Pause,
91}
92
93#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
94pub struct StripePriceId(pub Arc<str>);
95
96#[derive(Debug, PartialEq, Clone)]
97pub struct StripePrice {
98 pub id: StripePriceId,
99 pub unit_amount: Option<i64>,
100 pub lookup_key: Option<String>,
101 pub recurring: Option<StripePriceRecurring>,
102}
103
104#[derive(Debug, PartialEq, Clone)]
105pub struct StripePriceRecurring {
106 pub meter: Option<String>,
107}
108
109#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Deserialize)]
110pub struct StripeMeterId(pub Arc<str>);
111
112#[derive(Debug, Clone, Deserialize)]
113pub struct StripeMeter {
114 pub id: StripeMeterId,
115 pub event_name: String,
116}
117
118#[derive(Debug, Serialize)]
119pub struct StripeCreateMeterEventParams<'a> {
120 pub identifier: &'a str,
121 pub event_name: &'a str,
122 pub payload: StripeCreateMeterEventPayload<'a>,
123 pub timestamp: Option<i64>,
124}
125
126#[derive(Debug, Serialize)]
127pub struct StripeCreateMeterEventPayload<'a> {
128 pub value: u64,
129 pub stripe_customer_id: &'a StripeCustomerId,
130}
131
132#[derive(Debug, Default)]
133pub struct StripeCreateCheckoutSessionParams<'a> {
134 pub customer: Option<&'a StripeCustomerId>,
135 pub client_reference_id: Option<&'a str>,
136 pub mode: Option<StripeCheckoutSessionMode>,
137 pub line_items: Option<Vec<StripeCreateCheckoutSessionLineItems>>,
138 pub payment_method_collection: Option<StripeCheckoutSessionPaymentMethodCollection>,
139 pub subscription_data: Option<StripeCreateCheckoutSessionSubscriptionData>,
140 pub success_url: Option<&'a str>,
141}
142
143#[derive(Debug, PartialEq, Eq, Clone, Copy)]
144pub enum StripeCheckoutSessionMode {
145 Payment,
146 Setup,
147 Subscription,
148}
149
150#[derive(Debug, PartialEq, Clone)]
151pub struct StripeCreateCheckoutSessionLineItems {
152 pub price: Option<String>,
153 pub quantity: Option<u64>,
154}
155
156#[derive(Debug, PartialEq, Eq, Clone, Copy)]
157pub enum StripeCheckoutSessionPaymentMethodCollection {
158 Always,
159 IfRequired,
160}
161
162#[derive(Debug, PartialEq, Clone)]
163pub struct StripeCreateCheckoutSessionSubscriptionData {
164 pub metadata: Option<HashMap<String, String>>,
165 pub trial_period_days: Option<u32>,
166 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
167}
168
169#[derive(Debug)]
170pub struct StripeCheckoutSession {
171 pub url: Option<String>,
172}
173
174#[async_trait]
175pub trait StripeClient: Send + Sync {
176 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>>;
177
178 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer>;
179
180 async fn list_subscriptions_for_customer(
181 &self,
182 customer_id: &StripeCustomerId,
183 ) -> Result<Vec<StripeSubscription>>;
184
185 async fn get_subscription(
186 &self,
187 subscription_id: &StripeSubscriptionId,
188 ) -> Result<StripeSubscription>;
189
190 async fn create_subscription(
191 &self,
192 params: StripeCreateSubscriptionParams,
193 ) -> Result<StripeSubscription>;
194
195 async fn update_subscription(
196 &self,
197 subscription_id: &StripeSubscriptionId,
198 params: UpdateSubscriptionParams,
199 ) -> Result<()>;
200
201 async fn list_prices(&self) -> Result<Vec<StripePrice>>;
202
203 async fn list_meters(&self) -> Result<Vec<StripeMeter>>;
204
205 async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()>;
206
207 async fn create_checkout_session(
208 &self,
209 params: StripeCreateCheckoutSessionParams<'_>,
210 ) -> Result<StripeCheckoutSession>;
211}