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)]
31pub struct UpdateCustomerParams<'a> {
32 pub email: Option<&'a str>,
33}
34
35#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
36pub struct StripeSubscriptionId(pub Arc<str>);
37
38#[derive(Debug, PartialEq, Clone)]
39pub struct StripeSubscription {
40 pub id: StripeSubscriptionId,
41 pub customer: StripeCustomerId,
42 // TODO: Create our own version of this enum.
43 pub status: stripe::SubscriptionStatus,
44 pub current_period_end: i64,
45 pub current_period_start: i64,
46 pub items: Vec<StripeSubscriptionItem>,
47 pub cancel_at: Option<i64>,
48 pub cancellation_details: Option<StripeCancellationDetails>,
49}
50
51#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
52pub struct StripeSubscriptionItemId(pub Arc<str>);
53
54#[derive(Debug, PartialEq, Clone)]
55pub struct StripeSubscriptionItem {
56 pub id: StripeSubscriptionItemId,
57 pub price: Option<StripePrice>,
58}
59
60#[derive(Debug, Clone, PartialEq)]
61pub struct StripeCancellationDetails {
62 pub reason: Option<StripeCancellationDetailsReason>,
63}
64
65#[derive(Debug, PartialEq, Eq, Clone, Copy)]
66pub enum StripeCancellationDetailsReason {
67 CancellationRequested,
68 PaymentDisputed,
69 PaymentFailed,
70}
71
72#[derive(Debug)]
73pub struct StripeCreateSubscriptionParams {
74 pub customer: StripeCustomerId,
75 pub items: Vec<StripeCreateSubscriptionItems>,
76}
77
78#[derive(Debug)]
79pub struct StripeCreateSubscriptionItems {
80 pub price: Option<StripePriceId>,
81 pub quantity: Option<u64>,
82}
83
84#[derive(Debug, Clone)]
85pub struct UpdateSubscriptionParams {
86 pub items: Option<Vec<UpdateSubscriptionItems>>,
87 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
88}
89
90#[derive(Debug, PartialEq, Clone)]
91pub struct UpdateSubscriptionItems {
92 pub price: Option<StripePriceId>,
93}
94
95#[derive(Debug, PartialEq, Clone)]
96pub struct StripeSubscriptionTrialSettings {
97 pub end_behavior: StripeSubscriptionTrialSettingsEndBehavior,
98}
99
100#[derive(Debug, PartialEq, Clone)]
101pub struct StripeSubscriptionTrialSettingsEndBehavior {
102 pub missing_payment_method: StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod,
103}
104
105#[derive(Debug, PartialEq, Eq, Clone, Copy)]
106pub enum StripeSubscriptionTrialSettingsEndBehaviorMissingPaymentMethod {
107 Cancel,
108 CreateInvoice,
109 Pause,
110}
111
112#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display)]
113pub struct StripePriceId(pub Arc<str>);
114
115#[derive(Debug, PartialEq, Clone)]
116pub struct StripePrice {
117 pub id: StripePriceId,
118 pub unit_amount: Option<i64>,
119 pub lookup_key: Option<String>,
120 pub recurring: Option<StripePriceRecurring>,
121}
122
123#[derive(Debug, PartialEq, Clone)]
124pub struct StripePriceRecurring {
125 pub meter: Option<String>,
126}
127
128#[derive(Debug, PartialEq, Eq, Hash, Clone, derive_more::Display, Deserialize)]
129pub struct StripeMeterId(pub Arc<str>);
130
131#[derive(Debug, Clone, Deserialize)]
132pub struct StripeMeter {
133 pub id: StripeMeterId,
134 pub event_name: String,
135}
136
137#[derive(Debug, Serialize)]
138pub struct StripeCreateMeterEventParams<'a> {
139 pub identifier: &'a str,
140 pub event_name: &'a str,
141 pub payload: StripeCreateMeterEventPayload<'a>,
142 pub timestamp: Option<i64>,
143}
144
145#[derive(Debug, Serialize)]
146pub struct StripeCreateMeterEventPayload<'a> {
147 pub value: u64,
148 pub stripe_customer_id: &'a StripeCustomerId,
149}
150
151#[derive(Debug, PartialEq, Eq, Clone, Copy)]
152pub enum StripeBillingAddressCollection {
153 Auto,
154 Required,
155}
156
157#[derive(Debug, Default)]
158pub struct StripeCreateCheckoutSessionParams<'a> {
159 pub customer: Option<&'a StripeCustomerId>,
160 pub client_reference_id: Option<&'a str>,
161 pub mode: Option<StripeCheckoutSessionMode>,
162 pub line_items: Option<Vec<StripeCreateCheckoutSessionLineItems>>,
163 pub payment_method_collection: Option<StripeCheckoutSessionPaymentMethodCollection>,
164 pub subscription_data: Option<StripeCreateCheckoutSessionSubscriptionData>,
165 pub success_url: Option<&'a str>,
166 pub billing_address_collection: Option<StripeBillingAddressCollection>,
167}
168
169#[derive(Debug, PartialEq, Eq, Clone, Copy)]
170pub enum StripeCheckoutSessionMode {
171 Payment,
172 Setup,
173 Subscription,
174}
175
176#[derive(Debug, PartialEq, Clone)]
177pub struct StripeCreateCheckoutSessionLineItems {
178 pub price: Option<String>,
179 pub quantity: Option<u64>,
180}
181
182#[derive(Debug, PartialEq, Eq, Clone, Copy)]
183pub enum StripeCheckoutSessionPaymentMethodCollection {
184 Always,
185 IfRequired,
186}
187
188#[derive(Debug, PartialEq, Clone)]
189pub struct StripeCreateCheckoutSessionSubscriptionData {
190 pub metadata: Option<HashMap<String, String>>,
191 pub trial_period_days: Option<u32>,
192 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
193}
194
195#[derive(Debug)]
196pub struct StripeCheckoutSession {
197 pub url: Option<String>,
198}
199
200#[async_trait]
201pub trait StripeClient: Send + Sync {
202 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>>;
203
204 async fn get_customer(&self, customer_id: &StripeCustomerId) -> Result<StripeCustomer>;
205
206 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer>;
207
208 async fn update_customer(
209 &self,
210 customer_id: &StripeCustomerId,
211 params: UpdateCustomerParams<'_>,
212 ) -> Result<StripeCustomer>;
213
214 async fn list_subscriptions_for_customer(
215 &self,
216 customer_id: &StripeCustomerId,
217 ) -> Result<Vec<StripeSubscription>>;
218
219 async fn get_subscription(
220 &self,
221 subscription_id: &StripeSubscriptionId,
222 ) -> Result<StripeSubscription>;
223
224 async fn create_subscription(
225 &self,
226 params: StripeCreateSubscriptionParams,
227 ) -> Result<StripeSubscription>;
228
229 async fn update_subscription(
230 &self,
231 subscription_id: &StripeSubscriptionId,
232 params: UpdateSubscriptionParams,
233 ) -> Result<()>;
234
235 async fn cancel_subscription(&self, subscription_id: &StripeSubscriptionId) -> Result<()>;
236
237 async fn list_prices(&self) -> Result<Vec<StripePrice>>;
238
239 async fn list_meters(&self) -> Result<Vec<StripeMeter>>;
240
241 async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()>;
242
243 async fn create_checkout_session(
244 &self,
245 params: StripeCreateCheckoutSessionParams<'_>,
246 ) -> Result<StripeCheckoutSession>;
247}