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, PartialEq, Clone)]
158pub struct StripeCustomerUpdate {
159 pub address: Option<StripeCustomerUpdateAddress>,
160 pub name: Option<StripeCustomerUpdateName>,
161 pub shipping: Option<StripeCustomerUpdateShipping>,
162}
163
164#[derive(Debug, PartialEq, Eq, Clone, Copy)]
165pub enum StripeCustomerUpdateAddress {
166 Auto,
167 Never,
168}
169
170#[derive(Debug, PartialEq, Eq, Clone, Copy)]
171pub enum StripeCustomerUpdateName {
172 Auto,
173 Never,
174}
175
176#[derive(Debug, PartialEq, Eq, Clone, Copy)]
177pub enum StripeCustomerUpdateShipping {
178 Auto,
179 Never,
180}
181
182#[derive(Debug, Default)]
183pub struct StripeCreateCheckoutSessionParams<'a> {
184 pub customer: Option<&'a StripeCustomerId>,
185 pub client_reference_id: Option<&'a str>,
186 pub mode: Option<StripeCheckoutSessionMode>,
187 pub line_items: Option<Vec<StripeCreateCheckoutSessionLineItems>>,
188 pub payment_method_collection: Option<StripeCheckoutSessionPaymentMethodCollection>,
189 pub subscription_data: Option<StripeCreateCheckoutSessionSubscriptionData>,
190 pub success_url: Option<&'a str>,
191 pub billing_address_collection: Option<StripeBillingAddressCollection>,
192 pub customer_update: Option<StripeCustomerUpdate>,
193}
194
195#[derive(Debug, PartialEq, Eq, Clone, Copy)]
196pub enum StripeCheckoutSessionMode {
197 Payment,
198 Setup,
199 Subscription,
200}
201
202#[derive(Debug, PartialEq, Clone)]
203pub struct StripeCreateCheckoutSessionLineItems {
204 pub price: Option<String>,
205 pub quantity: Option<u64>,
206}
207
208#[derive(Debug, PartialEq, Eq, Clone, Copy)]
209pub enum StripeCheckoutSessionPaymentMethodCollection {
210 Always,
211 IfRequired,
212}
213
214#[derive(Debug, PartialEq, Clone)]
215pub struct StripeCreateCheckoutSessionSubscriptionData {
216 pub metadata: Option<HashMap<String, String>>,
217 pub trial_period_days: Option<u32>,
218 pub trial_settings: Option<StripeSubscriptionTrialSettings>,
219}
220
221#[derive(Debug)]
222pub struct StripeCheckoutSession {
223 pub url: Option<String>,
224}
225
226#[async_trait]
227pub trait StripeClient: Send + Sync {
228 async fn list_customers_by_email(&self, email: &str) -> Result<Vec<StripeCustomer>>;
229
230 async fn get_customer(&self, customer_id: &StripeCustomerId) -> Result<StripeCustomer>;
231
232 async fn create_customer(&self, params: CreateCustomerParams<'_>) -> Result<StripeCustomer>;
233
234 async fn update_customer(
235 &self,
236 customer_id: &StripeCustomerId,
237 params: UpdateCustomerParams<'_>,
238 ) -> Result<StripeCustomer>;
239
240 async fn list_subscriptions_for_customer(
241 &self,
242 customer_id: &StripeCustomerId,
243 ) -> Result<Vec<StripeSubscription>>;
244
245 async fn get_subscription(
246 &self,
247 subscription_id: &StripeSubscriptionId,
248 ) -> Result<StripeSubscription>;
249
250 async fn create_subscription(
251 &self,
252 params: StripeCreateSubscriptionParams,
253 ) -> Result<StripeSubscription>;
254
255 async fn update_subscription(
256 &self,
257 subscription_id: &StripeSubscriptionId,
258 params: UpdateSubscriptionParams,
259 ) -> Result<()>;
260
261 async fn cancel_subscription(&self, subscription_id: &StripeSubscriptionId) -> Result<()>;
262
263 async fn list_prices(&self) -> Result<Vec<StripePrice>>;
264
265 async fn list_meters(&self) -> Result<Vec<StripeMeter>>;
266
267 async fn create_meter_event(&self, params: StripeCreateMeterEventParams<'_>) -> Result<()>;
268
269 async fn create_checkout_session(
270 &self,
271 params: StripeCreateCheckoutSessionParams<'_>,
272 ) -> Result<StripeCheckoutSession>;
273}