Class: UsageCredits::CreditPack

Inherits:
Object
  • Object
show all
Defined in:
lib/usage_credits/models/credit_pack.rb

Overview

A DSL to define credit packs that users can buy as one-time purchases.

Credit packs can be purchased independently and separately from any subscription.

The actual credit fulfillment is handled by the PayChargeExtension.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ CreditPack

Returns a new instance of CreditPack.



18
19
20
21
22
23
24
25
# File 'lib/usage_credits/models/credit_pack.rb', line 18

def initialize(name)
  @name = name
  @credits = 0
  @bonus_credits = 0
  @price_cents = 0
  @price_currency = UsageCredits.configuration.default_currency.to_s.upcase
   = {}
end

Instance Attribute Details

#bonus_creditsObject (readonly)

Returns the value of attribute bonus_credits.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def bonus_credits
  @bonus_credits
end

#creditsObject (readonly)

Returns the value of attribute credits.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def credits
  @credits
end

#metadataObject (readonly)

Returns the value of attribute metadata.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def 
  
end

#nameObject (readonly)

Returns the value of attribute name.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def name
  @name
end

#price_centsObject (readonly)

Returns the value of attribute price_cents.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def price_cents
  @price_cents
end

#price_currencyObject (readonly)

Returns the value of attribute price_currency.



13
14
15
# File 'lib/usage_credits/models/credit_pack.rb', line 13

def price_currency
  @price_currency
end

Instance Method Details

#base_metadataObject



148
149
150
151
152
153
154
155
156
157
# File 'lib/usage_credits/models/credit_pack.rb', line 148

def 
  {
    purchase_type: "credit_pack",
    pack_name: name,
    credits: credits,
    bonus_credits: bonus_credits,
    price_cents: price_cents,
    price_currency: price_currency
  }
end

#bonus(amount) ⇒ Object

Set bonus credits (e.g., for promotions)



37
38
39
# File 'lib/usage_credits/models/credit_pack.rb', line 37

def bonus(amount)
  @bonus_credits = amount.to_i
end

#button_textObject

Generate human-friendly button text for purchase links



118
119
120
# File 'lib/usage_credits/models/credit_pack.rb', line 118

def button_text
  "Get #{display_credits} for #{formatted_price}"
end

#costs(cents) ⇒ Object Also known as: cost

Set the price in cents (e.g., 4900 for $49.00)



42
43
44
# File 'lib/usage_credits/models/credit_pack.rb', line 42

def costs(cents)
  @price_cents = cents
end

#create_checkout_session(user) ⇒ Object

Create a Stripe Checkout session for this pack

Raises:

  • (ArgumentError)


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/usage_credits/models/credit_pack.rb', line 127

def create_checkout_session(user)
  raise ArgumentError, "User must have a payment processor" unless user.respond_to?(:payment_processor) && user.payment_processor

  user.payment_processor.checkout(
    mode: "payment",
    line_items: [{
      price_data: {
        currency: price_currency.downcase,
        unit_amount: price_cents,
        product_data: {
          name: display_name,
          description: display_description
        }
      },
      quantity: 1
    }],
    payment_intent_data: { metadata:  },
    metadata: 
  )
end

#credits_per_dollarObject

Get credits per dollar ratio (for comparison)



95
96
97
98
# File 'lib/usage_credits/models/credit_pack.rb', line 95

def credits_per_dollar
  return 0 if price.zero?
  total_credits / price
end

#currency(currency) ⇒ Object

Set the currency (defaults to configuration)



48
49
50
51
52
53
54
# File 'lib/usage_credits/models/credit_pack.rb', line 48

def currency(currency)
  currency = currency.to_s.downcase.to_sym
  unless UsageCredits::Configuration::VALID_CURRENCIES.include?(currency)
    raise ArgumentError, "Invalid currency. Must be one of: #{UsageCredits::Configuration::VALID_CURRENCIES.join(', ')}"
  end
  @price_currency = currency.to_s.upcase
end

#display_creditsObject Also known as: display_description

Display Formatting



104
105
106
107
108
109
110
# File 'lib/usage_credits/models/credit_pack.rb', line 104

def display_credits
  if bonus_credits.positive?
    "#{credits} + #{bonus_credits} bonus credits"
  else
    "#{credits} credits"
  end
end

#display_nameObject



113
114
115
# File 'lib/usage_credits/models/credit_pack.rb', line 113

def display_name
  "#{name.to_s.titleize} pack"
end

#formatted_priceObject

Get formatted price (e.g., “49.00 USD”)



90
91
92
# File 'lib/usage_credits/models/credit_pack.rb', line 90

def formatted_price
  format("%.2f %s", price, price_currency)
end

#gives(amount) ⇒ Object

Set the base number of credits



32
33
34
# File 'lib/usage_credits/models/credit_pack.rb', line 32

def gives(amount)
  @credits = amount.to_i
end

#meta(hash) ⇒ Object

Add custom metadata



57
58
59
# File 'lib/usage_credits/models/credit_pack.rb', line 57

def meta(hash)
  .merge!(hash.transform_keys(&:to_sym))
end

#priceObject

Get price in dollars



85
86
87
# File 'lib/usage_credits/models/credit_pack.rb', line 85

def price
  price_cents / 100.0
end

#total_creditsObject

Get total credits (including bonus)



80
81
82
# File 'lib/usage_credits/models/credit_pack.rb', line 80

def total_credits
  credits + bonus_credits
end

#validate!Object

Validation

Raises:

  • (ArgumentError)


65
66
67
68
69
70
71
72
73
# File 'lib/usage_credits/models/credit_pack.rb', line 65

def validate!
  raise ArgumentError, "Name can't be blank" if name.blank?
  raise ArgumentError, "Credits must be greater than 0" unless credits.to_i.positive?
  raise ArgumentError, "Bonus credits must be greater than or equal to 0" if bonus_credits.to_i.negative?
  raise ArgumentError, "Price must be greater than 0" unless price_cents.to_i.positive?
  raise ArgumentError, "Currency can't be blank" if price_currency.blank?
  # raise ArgumentError, "Price must be in whole cents ($49 = 4900)" if price_cents % 100 != 0 # Payment processors should handle this anyways
  true
end