dodopayments 2.20.1 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -1
- data/lib/dodopayments/models/checkout_session_preview_response.rb +30 -4
- data/lib/dodopayments/models/credit_entitlements/balance_create_ledger_entry_params.rb +4 -2
- data/lib/dodopayments/models/discount.rb +95 -3
- data/lib/dodopayments/models/discount_create_params.rb +110 -3
- data/lib/dodopayments/models/discount_list_params.rb +7 -2
- data/lib/dodopayments/models/discount_type.rb +1 -0
- data/lib/dodopayments/models/discount_update_params.rb +108 -3
- data/lib/dodopayments/models/payment.rb +145 -1
- data/lib/dodopayments/models/payment_list_params.rb +163 -1
- data/lib/dodopayments/models/payment_method_types.rb +0 -1
- data/lib/dodopayments/models/price.rb +19 -1
- data/lib/dodopayments/models/subscription.rb +11 -1
- data/lib/dodopayments/models/subscription_create_response.rb +10 -1
- data/lib/dodopayments/models/subscription_list_response.rb +11 -1
- data/lib/dodopayments/resources/credit_entitlements/balances.rb +1 -1
- data/lib/dodopayments/resources/discounts.rb +24 -5
- data/lib/dodopayments/resources/payments.rb +3 -1
- data/lib/dodopayments/version.rb +1 -1
- data/rbi/dodopayments/models/checkout_session_preview_response.rbi +33 -5
- data/rbi/dodopayments/models/credit_entitlements/balance_create_ledger_entry_params.rbi +6 -2
- data/rbi/dodopayments/models/discount.rbi +151 -2
- data/rbi/dodopayments/models/discount_create_params.rbi +197 -2
- data/rbi/dodopayments/models/discount_list_params.rbi +6 -2
- data/rbi/dodopayments/models/discount_type.rbi +1 -0
- data/rbi/dodopayments/models/discount_update_params.rbi +193 -2
- data/rbi/dodopayments/models/payment.rbi +347 -0
- data/rbi/dodopayments/models/payment_list_params.rbi +327 -0
- data/rbi/dodopayments/models/payment_method_types.rbi +0 -1
- data/rbi/dodopayments/models/price.rbi +20 -0
- data/rbi/dodopayments/models/subscription.rbi +15 -3
- data/rbi/dodopayments/models/subscription_create_response.rbi +13 -3
- data/rbi/dodopayments/models/subscription_list_response.rbi +15 -3
- data/rbi/dodopayments/resources/credit_entitlements/balances.rbi +3 -1
- data/rbi/dodopayments/resources/discounts.rbi +57 -3
- data/rbi/dodopayments/resources/payments.rbi +3 -0
- data/sig/dodopayments/models/checkout_session_preview_response.rbs +13 -3
- data/sig/dodopayments/models/discount.rbs +69 -0
- data/sig/dodopayments/models/discount_create_params.rbs +69 -0
- data/sig/dodopayments/models/discount_type.rbs +2 -1
- data/sig/dodopayments/models/discount_update_params.rbs +69 -0
- data/sig/dodopayments/models/payment.rbs +135 -0
- data/sig/dodopayments/models/payment_list_params.rbs +308 -0
- data/sig/dodopayments/models/payment_method_types.rbs +0 -2
- data/sig/dodopayments/models/price.rbs +10 -0
- data/sig/dodopayments/models/subscription.rbs +8 -3
- data/sig/dodopayments/models/subscription_create_response.rbs +8 -3
- data/sig/dodopayments/models/subscription_list_response.rbs +8 -3
- data/sig/dodopayments/resources/discounts.rbs +8 -0
- data/sig/dodopayments/resources/payments.rbs +1 -0
- metadata +2 -2
|
@@ -99,6 +99,17 @@ module Dodopayments
|
|
|
99
99
|
sig { returns(T.nilable(Integer)) }
|
|
100
100
|
attr_accessor :total_tax
|
|
101
101
|
|
|
102
|
+
# Per-unit trial amount after discounts, in the price currency's minor units
|
|
103
|
+
# (pre-quantity, pre-tax; see `current_breakup` for the taxed total due today).
|
|
104
|
+
# Only present for a paid trial; `None` for a free trial or no trial.
|
|
105
|
+
sig { returns(T.nilable(Integer)) }
|
|
106
|
+
attr_accessor :trial_amount
|
|
107
|
+
|
|
108
|
+
# Effective trial duration in days for the subscription line, when there's a trial
|
|
109
|
+
# (free or paid). `None` if no subscription or no trial.
|
|
110
|
+
sig { returns(T.nilable(Integer)) }
|
|
111
|
+
attr_accessor :trial_period_days
|
|
112
|
+
|
|
102
113
|
# Data returned by the calculate checkout session API
|
|
103
114
|
sig do
|
|
104
115
|
params(
|
|
@@ -120,7 +131,9 @@ module Dodopayments
|
|
|
120
131
|
tax_id_business_name: T.nilable(String),
|
|
121
132
|
tax_id_err_msg: T.nilable(String),
|
|
122
133
|
tax_id_format_name: T.nilable(String),
|
|
123
|
-
total_tax: T.nilable(Integer)
|
|
134
|
+
total_tax: T.nilable(Integer),
|
|
135
|
+
trial_amount: T.nilable(Integer),
|
|
136
|
+
trial_period_days: T.nilable(Integer)
|
|
124
137
|
).returns(T.attached_class)
|
|
125
138
|
end
|
|
126
139
|
def self.new(
|
|
@@ -153,7 +166,14 @@ module Dodopayments
|
|
|
153
166
|
# The matched tax ID notation (e.g. "VAT Number", "GSTIN") when valid
|
|
154
167
|
tax_id_format_name: nil,
|
|
155
168
|
# Total tax
|
|
156
|
-
total_tax: nil
|
|
169
|
+
total_tax: nil,
|
|
170
|
+
# Per-unit trial amount after discounts, in the price currency's minor units
|
|
171
|
+
# (pre-quantity, pre-tax; see `current_breakup` for the taxed total due today).
|
|
172
|
+
# Only present for a paid trial; `None` for a free trial or no trial.
|
|
173
|
+
trial_amount: nil,
|
|
174
|
+
# Effective trial duration in days for the subscription line, when there's a trial
|
|
175
|
+
# (free or paid). `None` if no subscription or no trial.
|
|
176
|
+
trial_period_days: nil
|
|
157
177
|
)
|
|
158
178
|
end
|
|
159
179
|
|
|
@@ -178,7 +198,9 @@ module Dodopayments
|
|
|
178
198
|
tax_id_business_name: T.nilable(String),
|
|
179
199
|
tax_id_err_msg: T.nilable(String),
|
|
180
200
|
tax_id_format_name: T.nilable(String),
|
|
181
|
-
total_tax: T.nilable(Integer)
|
|
201
|
+
total_tax: T.nilable(Integer),
|
|
202
|
+
trial_amount: T.nilable(Integer),
|
|
203
|
+
trial_period_days: T.nilable(Integer)
|
|
182
204
|
}
|
|
183
205
|
)
|
|
184
206
|
end
|
|
@@ -330,7 +352,8 @@ module Dodopayments
|
|
|
330
352
|
sig { returns(T.nilable(String)) }
|
|
331
353
|
attr_accessor :description
|
|
332
354
|
|
|
333
|
-
#
|
|
355
|
+
# Percentage rate (basis points) of the applicable percentage code; null for flat
|
|
356
|
+
# codes (their deduction is `og_price - discounted_price`).
|
|
334
357
|
sig { returns(T.nilable(Integer)) }
|
|
335
358
|
attr_accessor :discount_amount
|
|
336
359
|
|
|
@@ -407,7 +430,8 @@ module Dodopayments
|
|
|
407
430
|
tax_rate:,
|
|
408
431
|
addons: nil,
|
|
409
432
|
description: nil,
|
|
410
|
-
#
|
|
433
|
+
# Percentage rate (basis points) of the applicable percentage code; null for flat
|
|
434
|
+
# codes (their deduction is `og_price - discounted_price`).
|
|
411
435
|
discount_amount: nil,
|
|
412
436
|
# number of cycles the discount will apply
|
|
413
437
|
discount_cycle: nil,
|
|
@@ -619,6 +643,8 @@ module Dodopayments
|
|
|
619
643
|
sig { returns(T.nilable(String)) }
|
|
620
644
|
attr_accessor :description
|
|
621
645
|
|
|
646
|
+
# Percentage rate (basis points) of the applicable percentage code; null for flat
|
|
647
|
+
# codes (their deduction is `og_price - discounted_price`).
|
|
622
648
|
sig { returns(T.nilable(Integer)) }
|
|
623
649
|
attr_accessor :discount_amount
|
|
624
650
|
|
|
@@ -656,6 +682,8 @@ module Dodopayments
|
|
|
656
682
|
tax_inclusive:,
|
|
657
683
|
tax_rate:,
|
|
658
684
|
description: nil,
|
|
685
|
+
# Percentage rate (basis points) of the applicable percentage code; null for flat
|
|
686
|
+
# codes (their deduction is `og_price - discounted_price`).
|
|
659
687
|
discount_amount: nil,
|
|
660
688
|
tax: nil
|
|
661
689
|
)
|
|
@@ -21,7 +21,9 @@ module Dodopayments
|
|
|
21
21
|
sig { returns(String) }
|
|
22
22
|
attr_accessor :customer_id
|
|
23
23
|
|
|
24
|
-
# Amount to credit or debit
|
|
24
|
+
# Amount to credit or debit. Bounded to a `NUMERIC(38,28)` column, so the integer
|
|
25
|
+
# part must have fewer than 10 digits (< 10^10); larger values previously reached
|
|
26
|
+
# the DB and failed with a 22003 overflow surfaced as a 500.
|
|
25
27
|
sig { returns(String) }
|
|
26
28
|
attr_accessor :amount
|
|
27
29
|
|
|
@@ -70,7 +72,9 @@ module Dodopayments
|
|
|
70
72
|
def self.new(
|
|
71
73
|
credit_entitlement_id:,
|
|
72
74
|
customer_id:,
|
|
73
|
-
# Amount to credit or debit
|
|
75
|
+
# Amount to credit or debit. Bounded to a `NUMERIC(38,28)` column, so the integer
|
|
76
|
+
# part must have fewer than 10 digits (< 10^10); larger values previously reached
|
|
77
|
+
# the DB and failed with a 22003 overflow surfaced as a 500.
|
|
74
78
|
amount:,
|
|
75
79
|
# Entry type: credit or debit
|
|
76
80
|
entry_type:,
|
|
@@ -24,6 +24,10 @@ module Dodopayments
|
|
|
24
24
|
sig { returns(Time) }
|
|
25
25
|
attr_accessor :created_at
|
|
26
26
|
|
|
27
|
+
# Who may redeem this discount code.
|
|
28
|
+
sig { returns(Dodopayments::Discount::CustomerEligibility::TaggedSymbol) }
|
|
29
|
+
attr_accessor :customer_eligibility
|
|
30
|
+
|
|
27
31
|
# The unique discount ID
|
|
28
32
|
sig { returns(String) }
|
|
29
33
|
attr_accessor :discount_id
|
|
@@ -45,10 +49,25 @@ module Dodopayments
|
|
|
45
49
|
sig { returns(Integer) }
|
|
46
50
|
attr_accessor :times_used
|
|
47
51
|
|
|
48
|
-
# The type of discount
|
|
52
|
+
# The type of discount (`percentage` or `flat`).
|
|
49
53
|
sig { returns(Dodopayments::DiscountType::TaggedSymbol) }
|
|
50
54
|
attr_accessor :type
|
|
51
55
|
|
|
56
|
+
# Per-currency options (flat deduction / percentage cap + minimum subtotal). Empty
|
|
57
|
+
# for discounts without any configured currency options.
|
|
58
|
+
sig do
|
|
59
|
+
returns(T.nilable(T::Array[Dodopayments::Discount::CurrencyOption]))
|
|
60
|
+
end
|
|
61
|
+
attr_reader :currency_options
|
|
62
|
+
|
|
63
|
+
sig do
|
|
64
|
+
params(
|
|
65
|
+
currency_options:
|
|
66
|
+
T::Array[Dodopayments::Discount::CurrencyOption::OrHash]
|
|
67
|
+
).void
|
|
68
|
+
end
|
|
69
|
+
attr_writer :currency_options
|
|
70
|
+
|
|
52
71
|
# Optional date/time after which discount is expired.
|
|
53
72
|
sig { returns(T.nilable(Time)) }
|
|
54
73
|
attr_accessor :expires_at
|
|
@@ -57,6 +76,15 @@ module Dodopayments
|
|
|
57
76
|
sig { returns(T.nilable(String)) }
|
|
58
77
|
attr_accessor :name
|
|
59
78
|
|
|
79
|
+
# Maximum number of times a single customer may redeem this discount, if any.
|
|
80
|
+
sig { returns(T.nilable(Integer)) }
|
|
81
|
+
attr_accessor :per_customer_usage_limit
|
|
82
|
+
|
|
83
|
+
# Optional date/time before which the discount is not yet active. NULL = active
|
|
84
|
+
# immediately.
|
|
85
|
+
sig { returns(T.nilable(Time)) }
|
|
86
|
+
attr_accessor :starts_at
|
|
87
|
+
|
|
60
88
|
# Number of subscription billing cycles this discount is valid for. If not
|
|
61
89
|
# provided, the discount will be applied indefinitely to all recurring payments
|
|
62
90
|
# related to the subscription.
|
|
@@ -73,14 +101,20 @@ module Dodopayments
|
|
|
73
101
|
business_id: String,
|
|
74
102
|
code: String,
|
|
75
103
|
created_at: Time,
|
|
104
|
+
customer_eligibility:
|
|
105
|
+
Dodopayments::Discount::CustomerEligibility::OrSymbol,
|
|
76
106
|
discount_id: String,
|
|
77
107
|
metadata: T::Hash[Symbol, Dodopayments::MetadataItem::Variants],
|
|
78
108
|
preserve_on_plan_change: T::Boolean,
|
|
79
109
|
restricted_to: T::Array[String],
|
|
80
110
|
times_used: Integer,
|
|
81
111
|
type: Dodopayments::DiscountType::OrSymbol,
|
|
112
|
+
currency_options:
|
|
113
|
+
T::Array[Dodopayments::Discount::CurrencyOption::OrHash],
|
|
82
114
|
expires_at: T.nilable(Time),
|
|
83
115
|
name: T.nilable(String),
|
|
116
|
+
per_customer_usage_limit: T.nilable(Integer),
|
|
117
|
+
starts_at: T.nilable(Time),
|
|
84
118
|
subscription_cycles: T.nilable(Integer),
|
|
85
119
|
usage_limit: T.nilable(Integer)
|
|
86
120
|
).returns(T.attached_class)
|
|
@@ -94,6 +128,8 @@ module Dodopayments
|
|
|
94
128
|
code:,
|
|
95
129
|
# Timestamp when the discount is created
|
|
96
130
|
created_at:,
|
|
131
|
+
# Who may redeem this discount code.
|
|
132
|
+
customer_eligibility:,
|
|
97
133
|
# The unique discount ID
|
|
98
134
|
discount_id:,
|
|
99
135
|
# Arbitrary key-value metadata. Values can be string, integer, number, or boolean.
|
|
@@ -105,12 +141,20 @@ module Dodopayments
|
|
|
105
141
|
restricted_to:,
|
|
106
142
|
# How many times this discount has been used.
|
|
107
143
|
times_used:,
|
|
108
|
-
# The type of discount
|
|
144
|
+
# The type of discount (`percentage` or `flat`).
|
|
109
145
|
type:,
|
|
146
|
+
# Per-currency options (flat deduction / percentage cap + minimum subtotal). Empty
|
|
147
|
+
# for discounts without any configured currency options.
|
|
148
|
+
currency_options: nil,
|
|
110
149
|
# Optional date/time after which discount is expired.
|
|
111
150
|
expires_at: nil,
|
|
112
151
|
# Name for the Discount
|
|
113
152
|
name: nil,
|
|
153
|
+
# Maximum number of times a single customer may redeem this discount, if any.
|
|
154
|
+
per_customer_usage_limit: nil,
|
|
155
|
+
# Optional date/time before which the discount is not yet active. NULL = active
|
|
156
|
+
# immediately.
|
|
157
|
+
starts_at: nil,
|
|
114
158
|
# Number of subscription billing cycles this discount is valid for. If not
|
|
115
159
|
# provided, the discount will be applied indefinitely to all recurring payments
|
|
116
160
|
# related to the subscription.
|
|
@@ -127,14 +171,19 @@ module Dodopayments
|
|
|
127
171
|
business_id: String,
|
|
128
172
|
code: String,
|
|
129
173
|
created_at: Time,
|
|
174
|
+
customer_eligibility:
|
|
175
|
+
Dodopayments::Discount::CustomerEligibility::TaggedSymbol,
|
|
130
176
|
discount_id: String,
|
|
131
177
|
metadata: T::Hash[Symbol, Dodopayments::MetadataItem::Variants],
|
|
132
178
|
preserve_on_plan_change: T::Boolean,
|
|
133
179
|
restricted_to: T::Array[String],
|
|
134
180
|
times_used: Integer,
|
|
135
181
|
type: Dodopayments::DiscountType::TaggedSymbol,
|
|
182
|
+
currency_options: T::Array[Dodopayments::Discount::CurrencyOption],
|
|
136
183
|
expires_at: T.nilable(Time),
|
|
137
184
|
name: T.nilable(String),
|
|
185
|
+
per_customer_usage_limit: T.nilable(Integer),
|
|
186
|
+
starts_at: T.nilable(Time),
|
|
138
187
|
subscription_cycles: T.nilable(Integer),
|
|
139
188
|
usage_limit: T.nilable(Integer)
|
|
140
189
|
}
|
|
@@ -142,6 +191,106 @@ module Dodopayments
|
|
|
142
191
|
end
|
|
143
192
|
def to_hash
|
|
144
193
|
end
|
|
194
|
+
|
|
195
|
+
# Who may redeem this discount code.
|
|
196
|
+
module CustomerEligibility
|
|
197
|
+
extend Dodopayments::Internal::Type::Enum
|
|
198
|
+
|
|
199
|
+
TaggedSymbol =
|
|
200
|
+
T.type_alias do
|
|
201
|
+
T.all(Symbol, Dodopayments::Discount::CustomerEligibility)
|
|
202
|
+
end
|
|
203
|
+
OrSymbol = T.type_alias { T.any(Symbol, String) }
|
|
204
|
+
|
|
205
|
+
ANY =
|
|
206
|
+
T.let(:any, Dodopayments::Discount::CustomerEligibility::TaggedSymbol)
|
|
207
|
+
FIRST_TIME =
|
|
208
|
+
T.let(
|
|
209
|
+
:first_time,
|
|
210
|
+
Dodopayments::Discount::CustomerEligibility::TaggedSymbol
|
|
211
|
+
)
|
|
212
|
+
EXISTING =
|
|
213
|
+
T.let(
|
|
214
|
+
:existing,
|
|
215
|
+
Dodopayments::Discount::CustomerEligibility::TaggedSymbol
|
|
216
|
+
)
|
|
217
|
+
SPECIFIC =
|
|
218
|
+
T.let(
|
|
219
|
+
:specific,
|
|
220
|
+
Dodopayments::Discount::CustomerEligibility::TaggedSymbol
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
sig do
|
|
224
|
+
override.returns(
|
|
225
|
+
T::Array[Dodopayments::Discount::CustomerEligibility::TaggedSymbol]
|
|
226
|
+
)
|
|
227
|
+
end
|
|
228
|
+
def self.values
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
class CurrencyOption < Dodopayments::Internal::Type::BaseModel
|
|
233
|
+
OrHash =
|
|
234
|
+
T.type_alias do
|
|
235
|
+
T.any(
|
|
236
|
+
Dodopayments::Discount::CurrencyOption,
|
|
237
|
+
Dodopayments::Internal::AnyHash
|
|
238
|
+
)
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# The currency this option applies to.
|
|
242
|
+
sig { returns(Dodopayments::Currency::TaggedSymbol) }
|
|
243
|
+
attr_accessor :currency
|
|
244
|
+
|
|
245
|
+
# Whether this is the default row FX conversions pivot from.
|
|
246
|
+
sig { returns(T::Boolean) }
|
|
247
|
+
attr_accessor :is_default
|
|
248
|
+
|
|
249
|
+
# Eligible-cart threshold in this currency's subunits (0 = no minimum).
|
|
250
|
+
sig { returns(Integer) }
|
|
251
|
+
attr_accessor :minimum_subtotal
|
|
252
|
+
|
|
253
|
+
# The most this code discounts in this currency's subunits (flat deduction or
|
|
254
|
+
# percentage cap).
|
|
255
|
+
sig { returns(T.nilable(Integer)) }
|
|
256
|
+
attr_accessor :max_amount_possible
|
|
257
|
+
|
|
258
|
+
# A per-currency discount option (response shape). `max_amount_possible` mirrors
|
|
259
|
+
# the DB column of the same name.
|
|
260
|
+
sig do
|
|
261
|
+
params(
|
|
262
|
+
currency: Dodopayments::Currency::OrSymbol,
|
|
263
|
+
is_default: T::Boolean,
|
|
264
|
+
minimum_subtotal: Integer,
|
|
265
|
+
max_amount_possible: T.nilable(Integer)
|
|
266
|
+
).returns(T.attached_class)
|
|
267
|
+
end
|
|
268
|
+
def self.new(
|
|
269
|
+
# The currency this option applies to.
|
|
270
|
+
currency:,
|
|
271
|
+
# Whether this is the default row FX conversions pivot from.
|
|
272
|
+
is_default:,
|
|
273
|
+
# Eligible-cart threshold in this currency's subunits (0 = no minimum).
|
|
274
|
+
minimum_subtotal:,
|
|
275
|
+
# The most this code discounts in this currency's subunits (flat deduction or
|
|
276
|
+
# percentage cap).
|
|
277
|
+
max_amount_possible: nil
|
|
278
|
+
)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
sig do
|
|
282
|
+
override.returns(
|
|
283
|
+
{
|
|
284
|
+
currency: Dodopayments::Currency::TaggedSymbol,
|
|
285
|
+
is_default: T::Boolean,
|
|
286
|
+
minimum_subtotal: Integer,
|
|
287
|
+
max_amount_possible: T.nilable(Integer)
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
end
|
|
291
|
+
def to_hash
|
|
292
|
+
end
|
|
293
|
+
end
|
|
145
294
|
end
|
|
146
295
|
end
|
|
147
296
|
end
|
|
@@ -21,7 +21,7 @@ module Dodopayments
|
|
|
21
21
|
sig { returns(Integer) }
|
|
22
22
|
attr_accessor :amount
|
|
23
23
|
|
|
24
|
-
# The discount type
|
|
24
|
+
# The discount type: `percentage` or `flat` (`flat_per_unit` stays blocked).
|
|
25
25
|
sig { returns(Dodopayments::DiscountType::OrSymbol) }
|
|
26
26
|
attr_accessor :type
|
|
27
27
|
|
|
@@ -32,6 +32,31 @@ module Dodopayments
|
|
|
32
32
|
sig { returns(T.nilable(String)) }
|
|
33
33
|
attr_accessor :code
|
|
34
34
|
|
|
35
|
+
# Per-currency options (flat deduction / percentage cap + minimum subtotal).
|
|
36
|
+
# Required for `flat` codes (must include a resolvable default); optional
|
|
37
|
+
# per-currency caps for `percentage` codes. Per-row invariants are checked in
|
|
38
|
+
# `normalize_currency_options`, not via `#[validate(nested)]`.
|
|
39
|
+
sig do
|
|
40
|
+
returns(
|
|
41
|
+
T.nilable(
|
|
42
|
+
T::Array[Dodopayments::DiscountCreateParams::CurrencyOption]
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
attr_accessor :currency_options
|
|
47
|
+
|
|
48
|
+
# Who may redeem this discount code. Defaults to `any` (unrestricted). `specific`
|
|
49
|
+
# starts with zero attached customers (fails closed) until customers are attached
|
|
50
|
+
# via `POST /discounts/{id}/customers`.
|
|
51
|
+
sig do
|
|
52
|
+
returns(
|
|
53
|
+
T.nilable(
|
|
54
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::OrSymbol
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
attr_accessor :customer_eligibility
|
|
59
|
+
|
|
35
60
|
# When the discount expires, if ever.
|
|
36
61
|
sig { returns(T.nilable(Time)) }
|
|
37
62
|
attr_accessor :expires_at
|
|
@@ -54,6 +79,11 @@ module Dodopayments
|
|
|
54
79
|
sig { returns(T.nilable(String)) }
|
|
55
80
|
attr_accessor :name
|
|
56
81
|
|
|
82
|
+
# Maximum number of times a single customer may redeem this discount. Must be
|
|
83
|
+
# `<= usage_limit` when both are set.
|
|
84
|
+
sig { returns(T.nilable(Integer)) }
|
|
85
|
+
attr_accessor :per_customer_usage_limit
|
|
86
|
+
|
|
57
87
|
# Whether this discount should be preserved when a subscription changes plans.
|
|
58
88
|
# Default: false (discount is removed on plan change)
|
|
59
89
|
sig { returns(T.nilable(T::Boolean)) }
|
|
@@ -66,6 +96,11 @@ module Dodopayments
|
|
|
66
96
|
sig { returns(T.nilable(T::Array[String])) }
|
|
67
97
|
attr_accessor :restricted_to
|
|
68
98
|
|
|
99
|
+
# When the discount becomes active, if scheduled for the future. NULL = active
|
|
100
|
+
# immediately. Must be strictly before `expires_at` when both are set.
|
|
101
|
+
sig { returns(T.nilable(Time)) }
|
|
102
|
+
attr_accessor :starts_at
|
|
103
|
+
|
|
69
104
|
# Number of subscription billing cycles this discount is valid for. If not
|
|
70
105
|
# provided, the discount will be applied indefinitely to all recurring payments
|
|
71
106
|
# related to the subscription.
|
|
@@ -81,11 +116,23 @@ module Dodopayments
|
|
|
81
116
|
amount: Integer,
|
|
82
117
|
type: Dodopayments::DiscountType::OrSymbol,
|
|
83
118
|
code: T.nilable(String),
|
|
119
|
+
currency_options:
|
|
120
|
+
T.nilable(
|
|
121
|
+
T::Array[
|
|
122
|
+
Dodopayments::DiscountCreateParams::CurrencyOption::OrHash
|
|
123
|
+
]
|
|
124
|
+
),
|
|
125
|
+
customer_eligibility:
|
|
126
|
+
T.nilable(
|
|
127
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::OrSymbol
|
|
128
|
+
),
|
|
84
129
|
expires_at: T.nilable(Time),
|
|
85
130
|
metadata: T::Hash[Symbol, Dodopayments::MetadataItem::Variants],
|
|
86
131
|
name: T.nilable(String),
|
|
132
|
+
per_customer_usage_limit: T.nilable(Integer),
|
|
87
133
|
preserve_on_plan_change: T::Boolean,
|
|
88
134
|
restricted_to: T.nilable(T::Array[String]),
|
|
135
|
+
starts_at: T.nilable(Time),
|
|
89
136
|
subscription_cycles: T.nilable(Integer),
|
|
90
137
|
usage_limit: T.nilable(Integer),
|
|
91
138
|
request_options: Dodopayments::RequestOptions::OrHash
|
|
@@ -97,23 +144,38 @@ module Dodopayments
|
|
|
97
144
|
#
|
|
98
145
|
# Must be at least 1.
|
|
99
146
|
amount:,
|
|
100
|
-
# The discount type
|
|
147
|
+
# The discount type: `percentage` or `flat` (`flat_per_unit` stays blocked).
|
|
101
148
|
type:,
|
|
102
149
|
# Optionally supply a code (will be uppercased).
|
|
103
150
|
#
|
|
104
151
|
# - Must be at least 3 characters if provided.
|
|
105
152
|
# - If omitted, a random 16-character code is generated.
|
|
106
153
|
code: nil,
|
|
154
|
+
# Per-currency options (flat deduction / percentage cap + minimum subtotal).
|
|
155
|
+
# Required for `flat` codes (must include a resolvable default); optional
|
|
156
|
+
# per-currency caps for `percentage` codes. Per-row invariants are checked in
|
|
157
|
+
# `normalize_currency_options`, not via `#[validate(nested)]`.
|
|
158
|
+
currency_options: nil,
|
|
159
|
+
# Who may redeem this discount code. Defaults to `any` (unrestricted). `specific`
|
|
160
|
+
# starts with zero attached customers (fails closed) until customers are attached
|
|
161
|
+
# via `POST /discounts/{id}/customers`.
|
|
162
|
+
customer_eligibility: nil,
|
|
107
163
|
# When the discount expires, if ever.
|
|
108
164
|
expires_at: nil,
|
|
109
165
|
# Additional metadata for the discount
|
|
110
166
|
metadata: nil,
|
|
111
167
|
name: nil,
|
|
168
|
+
# Maximum number of times a single customer may redeem this discount. Must be
|
|
169
|
+
# `<= usage_limit` when both are set.
|
|
170
|
+
per_customer_usage_limit: nil,
|
|
112
171
|
# Whether this discount should be preserved when a subscription changes plans.
|
|
113
172
|
# Default: false (discount is removed on plan change)
|
|
114
173
|
preserve_on_plan_change: nil,
|
|
115
174
|
# List of product IDs to restrict usage (if any).
|
|
116
175
|
restricted_to: nil,
|
|
176
|
+
# When the discount becomes active, if scheduled for the future. NULL = active
|
|
177
|
+
# immediately. Must be strictly before `expires_at` when both are set.
|
|
178
|
+
starts_at: nil,
|
|
117
179
|
# Number of subscription billing cycles this discount is valid for. If not
|
|
118
180
|
# provided, the discount will be applied indefinitely to all recurring payments
|
|
119
181
|
# related to the subscription.
|
|
@@ -130,11 +192,21 @@ module Dodopayments
|
|
|
130
192
|
amount: Integer,
|
|
131
193
|
type: Dodopayments::DiscountType::OrSymbol,
|
|
132
194
|
code: T.nilable(String),
|
|
195
|
+
currency_options:
|
|
196
|
+
T.nilable(
|
|
197
|
+
T::Array[Dodopayments::DiscountCreateParams::CurrencyOption]
|
|
198
|
+
),
|
|
199
|
+
customer_eligibility:
|
|
200
|
+
T.nilable(
|
|
201
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::OrSymbol
|
|
202
|
+
),
|
|
133
203
|
expires_at: T.nilable(Time),
|
|
134
204
|
metadata: T::Hash[Symbol, Dodopayments::MetadataItem::Variants],
|
|
135
205
|
name: T.nilable(String),
|
|
206
|
+
per_customer_usage_limit: T.nilable(Integer),
|
|
136
207
|
preserve_on_plan_change: T::Boolean,
|
|
137
208
|
restricted_to: T.nilable(T::Array[String]),
|
|
209
|
+
starts_at: T.nilable(Time),
|
|
138
210
|
subscription_cycles: T.nilable(Integer),
|
|
139
211
|
usage_limit: T.nilable(Integer),
|
|
140
212
|
request_options: Dodopayments::RequestOptions
|
|
@@ -143,6 +215,129 @@ module Dodopayments
|
|
|
143
215
|
end
|
|
144
216
|
def to_hash
|
|
145
217
|
end
|
|
218
|
+
|
|
219
|
+
class CurrencyOption < Dodopayments::Internal::Type::BaseModel
|
|
220
|
+
OrHash =
|
|
221
|
+
T.type_alias do
|
|
222
|
+
T.any(
|
|
223
|
+
Dodopayments::DiscountCreateParams::CurrencyOption,
|
|
224
|
+
Dodopayments::Internal::AnyHash
|
|
225
|
+
)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# The currency this option applies to.
|
|
229
|
+
sig { returns(Dodopayments::Currency::OrSymbol) }
|
|
230
|
+
attr_accessor :currency
|
|
231
|
+
|
|
232
|
+
# Whether this row is the default to convert from for unconfigured currencies. At
|
|
233
|
+
# most one row per discount may be default.
|
|
234
|
+
sig { returns(T.nilable(T::Boolean)) }
|
|
235
|
+
attr_reader :is_default
|
|
236
|
+
|
|
237
|
+
sig { params(is_default: T::Boolean).void }
|
|
238
|
+
attr_writer :is_default
|
|
239
|
+
|
|
240
|
+
# The most this code discounts in this currency's subunits. For `flat` codes this
|
|
241
|
+
# is the deduction; for `percentage` codes it is the max-discount cap. Must be > 0
|
|
242
|
+
# if provided.
|
|
243
|
+
sig { returns(T.nilable(Integer)) }
|
|
244
|
+
attr_accessor :max_amount_possible
|
|
245
|
+
|
|
246
|
+
# Eligible-cart threshold in this currency's subunits (0 = no minimum).
|
|
247
|
+
sig { returns(T.nilable(Integer)) }
|
|
248
|
+
attr_reader :minimum_subtotal
|
|
249
|
+
|
|
250
|
+
sig { params(minimum_subtotal: Integer).void }
|
|
251
|
+
attr_writer :minimum_subtotal
|
|
252
|
+
|
|
253
|
+
# A per-currency discount option (request shape).
|
|
254
|
+
#
|
|
255
|
+
# `max_amount_possible` is the most this code discounts in this currency — the
|
|
256
|
+
# flat deduction for `flat` codes, or the max-discount cap for `percentage` codes.
|
|
257
|
+
# Maps to the DB column of the same name.
|
|
258
|
+
sig do
|
|
259
|
+
params(
|
|
260
|
+
currency: Dodopayments::Currency::OrSymbol,
|
|
261
|
+
is_default: T::Boolean,
|
|
262
|
+
max_amount_possible: T.nilable(Integer),
|
|
263
|
+
minimum_subtotal: Integer
|
|
264
|
+
).returns(T.attached_class)
|
|
265
|
+
end
|
|
266
|
+
def self.new(
|
|
267
|
+
# The currency this option applies to.
|
|
268
|
+
currency:,
|
|
269
|
+
# Whether this row is the default to convert from for unconfigured currencies. At
|
|
270
|
+
# most one row per discount may be default.
|
|
271
|
+
is_default: nil,
|
|
272
|
+
# The most this code discounts in this currency's subunits. For `flat` codes this
|
|
273
|
+
# is the deduction; for `percentage` codes it is the max-discount cap. Must be > 0
|
|
274
|
+
# if provided.
|
|
275
|
+
max_amount_possible: nil,
|
|
276
|
+
# Eligible-cart threshold in this currency's subunits (0 = no minimum).
|
|
277
|
+
minimum_subtotal: nil
|
|
278
|
+
)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
sig do
|
|
282
|
+
override.returns(
|
|
283
|
+
{
|
|
284
|
+
currency: Dodopayments::Currency::OrSymbol,
|
|
285
|
+
is_default: T::Boolean,
|
|
286
|
+
max_amount_possible: T.nilable(Integer),
|
|
287
|
+
minimum_subtotal: Integer
|
|
288
|
+
}
|
|
289
|
+
)
|
|
290
|
+
end
|
|
291
|
+
def to_hash
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Who may redeem this discount code. Defaults to `any` (unrestricted). `specific`
|
|
296
|
+
# starts with zero attached customers (fails closed) until customers are attached
|
|
297
|
+
# via `POST /discounts/{id}/customers`.
|
|
298
|
+
module CustomerEligibility
|
|
299
|
+
extend Dodopayments::Internal::Type::Enum
|
|
300
|
+
|
|
301
|
+
TaggedSymbol =
|
|
302
|
+
T.type_alias do
|
|
303
|
+
T.all(
|
|
304
|
+
Symbol,
|
|
305
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility
|
|
306
|
+
)
|
|
307
|
+
end
|
|
308
|
+
OrSymbol = T.type_alias { T.any(Symbol, String) }
|
|
309
|
+
|
|
310
|
+
ANY =
|
|
311
|
+
T.let(
|
|
312
|
+
:any,
|
|
313
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::TaggedSymbol
|
|
314
|
+
)
|
|
315
|
+
FIRST_TIME =
|
|
316
|
+
T.let(
|
|
317
|
+
:first_time,
|
|
318
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::TaggedSymbol
|
|
319
|
+
)
|
|
320
|
+
EXISTING =
|
|
321
|
+
T.let(
|
|
322
|
+
:existing,
|
|
323
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::TaggedSymbol
|
|
324
|
+
)
|
|
325
|
+
SPECIFIC =
|
|
326
|
+
T.let(
|
|
327
|
+
:specific,
|
|
328
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::TaggedSymbol
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
sig do
|
|
332
|
+
override.returns(
|
|
333
|
+
T::Array[
|
|
334
|
+
Dodopayments::DiscountCreateParams::CustomerEligibility::TaggedSymbol
|
|
335
|
+
]
|
|
336
|
+
)
|
|
337
|
+
end
|
|
338
|
+
def self.values
|
|
339
|
+
end
|
|
340
|
+
end
|
|
146
341
|
end
|
|
147
342
|
end
|
|
148
343
|
end
|
|
@@ -14,7 +14,9 @@ module Dodopayments
|
|
|
14
14
|
)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
# Filter by active status
|
|
17
|
+
# Filter by active status. `true` = currently redeemable (started, not expired,
|
|
18
|
+
# not usage-exhausted). `false` = not currently redeemable (expired,
|
|
19
|
+
# usage-exhausted, or pending a future `starts_at`).
|
|
18
20
|
sig { returns(T.nilable(T::Boolean)) }
|
|
19
21
|
attr_reader :active
|
|
20
22
|
|
|
@@ -68,7 +70,9 @@ module Dodopayments
|
|
|
68
70
|
).returns(T.attached_class)
|
|
69
71
|
end
|
|
70
72
|
def self.new(
|
|
71
|
-
# Filter by active status
|
|
73
|
+
# Filter by active status. `true` = currently redeemable (started, not expired,
|
|
74
|
+
# not usage-exhausted). `false` = not currently redeemable (expired,
|
|
75
|
+
# usage-exhausted, or pending a future `starts_at`).
|
|
72
76
|
active: nil,
|
|
73
77
|
# Filter by discount code (partial match, case-insensitive)
|
|
74
78
|
code: nil,
|
|
@@ -8,6 +8,7 @@ module Dodopayments
|
|
|
8
8
|
TaggedSymbol = T.type_alias { T.all(Symbol, Dodopayments::DiscountType) }
|
|
9
9
|
OrSymbol = T.type_alias { T.any(Symbol, String) }
|
|
10
10
|
|
|
11
|
+
FLAT = T.let(:flat, Dodopayments::DiscountType::TaggedSymbol)
|
|
11
12
|
PERCENTAGE = T.let(:percentage, Dodopayments::DiscountType::TaggedSymbol)
|
|
12
13
|
|
|
13
14
|
sig do
|