Module: Pay::Stripe
- Extended by:
- Env
- Defined in:
- lib/pay/stripe.rb,
app/models/pay/stripe/charge.rb,
app/models/pay/stripe/customer.rb,
app/models/pay/stripe/merchant.rb,
app/models/pay/stripe/subscription.rb,
app/models/pay/stripe/payment_method.rb,
lib/pay/stripe/webhooks/charge_updated.rb,
lib/pay/stripe/webhooks/payment_failed.rb,
lib/pay/stripe/webhooks/account_updated.rb,
lib/pay/stripe/webhooks/charge_refunded.rb,
lib/pay/stripe/webhooks/invoice_updated.rb,
lib/pay/stripe/webhooks/charge_succeeded.rb,
lib/pay/stripe/webhooks/customer_deleted.rb,
lib/pay/stripe/webhooks/customer_updated.rb,
lib/pay/stripe/webhooks/subscription_created.rb,
lib/pay/stripe/webhooks/subscription_deleted.rb,
lib/pay/stripe/webhooks/subscription_updated.rb,
lib/pay/stripe/webhooks/subscription_renewing.rb,
lib/pay/stripe/webhooks/payment_method_updated.rb,
lib/pay/stripe/webhooks/payment_action_required.rb,
lib/pay/stripe/webhooks/payment_method_attached.rb,
lib/pay/stripe/webhooks/payment_method_detached.rb,
lib/pay/stripe/webhooks/payment_intent_succeeded.rb,
lib/pay/stripe/webhooks/checkout_session_completed.rb,
lib/pay/stripe/webhooks/subscription_trial_will_end.rb,
lib/pay/stripe/webhooks/checkout_session_async_payment_succeeded.rb
Defined Under Namespace
Modules: Webhooks Classes: Charge, Customer, Error, Merchant, PaymentMethod, Subscription
Constant Summary collapse
- REQUIRED_VERSION =
"~> 19"
Class Method Summary collapse
- .configure_webhooks ⇒ Object
-
.context ⇒ Object
Optional.
- .enabled? ⇒ Boolean
- .find_by_client_reference_id(client_reference_id) ⇒ Object
- .private_key ⇒ Object
- .public_key ⇒ Object
- .setup ⇒ Object
- .signing_secret ⇒ Object
-
.sync_checkout_session(session_id, stripe_account: nil, try: 0, retries: 5) ⇒ Object
Subscriptions aren't always immediately associated, so we want to retry by default.
- .to_client_reference_id(record) ⇒ Object
- .webhook_receive_test_events ⇒ Object
Class Method Details
.configure_webhooks ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/pay/stripe.rb', line 89 def self.configure_webhooks Pay::Webhooks.configure do |events| # Listen to the charge event to make sure we get non-subscription # purchases as well. Invoice is only for subscriptions and manual creation # so it does not include individual charges. events.subscribe "stripe.charge.refunded", Pay::Stripe::Webhooks::ChargeRefunded.new events.subscribe "stripe.charge.succeeded", Pay::Stripe::Webhooks::ChargeSucceeded.new events.subscribe "stripe.charge.updated", Pay::Stripe::Webhooks::ChargeUpdated.new events.subscribe "stripe.payment_intent.succeeded", Pay::Stripe::Webhooks::PaymentIntentSucceeded.new # Warn user of upcoming charges for their subscription. This is handy for # notifying annual users their subscription will renew shortly. # This probably should be ignored for monthly subscriptions. events.subscribe "stripe.invoice.upcoming", Pay::Stripe::Webhooks::SubscriptionRenewing.new # Ensures the local stripe_object is up-to-date anytime the API's record is updated. events.subscribe "stripe.invoice.updated", Pay::Stripe::Webhooks::InvoiceUpdated.new # Payment action is required to process an invoice events.subscribe "stripe.invoice.payment_action_required", Pay::Stripe::Webhooks::PaymentActionRequired.new # If an invoice payment fails, we want to notify the user via email to update their payment details events.subscribe "stripe.invoice.payment_failed", Pay::Stripe::Webhooks::PaymentFailed.new # If a subscription is manually created on Stripe, we want to sync events.subscribe "stripe.customer.subscription.created", Pay::Stripe::Webhooks::SubscriptionCreated.new # If the plan, quantity, or trial ending date is updated on Stripe, we want to sync events.subscribe "stripe.customer.subscription.updated", Pay::Stripe::Webhooks::SubscriptionUpdated.new # When a customers subscription is canceled, we want to update our records events.subscribe "stripe.customer.subscription.deleted", Pay::Stripe::Webhooks::SubscriptionDeleted.new # When a customers subscription trial period is 3 days from ending or ended immediately this event is fired events.subscribe "stripe.customer.subscription.trial_will_end", Pay::Stripe::Webhooks::SubscriptionTrialWillEnd.new # Monitor changes for customer's default card changing and invoice credit updates events.subscribe "stripe.customer.updated", Pay::Stripe::Webhooks::CustomerUpdated.new # If a customer was deleted in Stripe, their subscriptions should be cancelled events.subscribe "stripe.customer.deleted", Pay::Stripe::Webhooks::CustomerDeleted.new # If a customer's payment source was deleted in Stripe, we should update as well events.subscribe "stripe.payment_method.attached", Pay::Stripe::Webhooks::PaymentMethodAttached.new events.subscribe "stripe.payment_method.updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new events.subscribe "stripe.payment_method.automatically_updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new events.subscribe "stripe.payment_method.card_automatically_updated", Pay::Stripe::Webhooks::PaymentMethodUpdated.new events.subscribe "stripe.payment_method.detached", Pay::Stripe::Webhooks::PaymentMethodDetached.new # If an account is updated in stripe, we should update it as well events.subscribe "stripe.account.updated", Pay::Stripe::Webhooks::AccountUpdated.new # Handle subscriptions in Stripe Checkout Sessions events.subscribe "stripe.checkout.session.completed", Pay::Stripe::Webhooks::CheckoutSessionCompleted.new events.subscribe "stripe.checkout.session.async_payment_succeeded", Pay::Stripe::Webhooks::CheckoutSessionAsyncPaymentSucceeded.new end end |
.context ⇒ Object
Optional. The account (acct_...) that API requests should act on when using a Stripe Organizations API key. Resolved like every other Stripe credential: ENV, then env-scoped, then unscoped Rails credentials.
76 77 78 |
# File 'lib/pay/stripe.rb', line 76 def self.context find_value_by_name(:stripe, :context) end |
.enabled? ⇒ Boolean
37 38 39 40 41 |
# File 'lib/pay/stripe.rb', line 37 def self.enabled? return false unless Pay.enabled_processors.include?(:stripe) && defined?(::Stripe) Pay::Engine.version_matches?(required: REQUIRED_VERSION, current: ::Stripe::VERSION) || (raise "[Pay] stripe gem must be version #{REQUIRED_VERSION}") end |
.find_by_client_reference_id(client_reference_id) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/pay/stripe.rb', line 153 def self.find_by_client_reference_id(client_reference_id) # If there is a client reference ID, make sure we have a Pay::Customer record # client_reference_id should be in the format of "User/1" model_name, id = client_reference_id.split("_", 2) # Only allow model names that use Pay return unless model_names.include?(model_name) model_name.constantize.find(id) rescue ActiveRecord::RecordNotFound Rails.logger.error "[Pay] Unable to locate record with: #{client_reference_id}" nil end |
.private_key ⇒ Object
68 69 70 |
# File 'lib/pay/stripe.rb', line 68 def self.private_key find_value_by_name(:stripe, :private_key) end |
.public_key ⇒ Object
64 65 66 |
# File 'lib/pay/stripe.rb', line 64 def self.public_key find_value_by_name(:stripe, :public_key) end |
.setup ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/pay/stripe.rb', line 43 def self.setup ::Stripe.api_key = private_key # When private_key is a Stripe Organizations API key (sk_org_...), # every request must identify the target account with the # Stripe-Context header. stripe-ruby applies this configuration to all # requests automatically. Regular account keys set no context and are # unaffected. https://docs.stripe.com/keys/organization-api-keys # (Assigned through Stripe.config: the Stripe module delegates # stripe_account but not stripe_context.) ::Stripe.config.stripe_context = context if context # Used by Stripe to identify Pay for support ::Stripe.set_app_info("PayRails", partner_id: "pp_partner_IqhY0UExnJYLxg", version: Pay::VERSION, url: "https://github.com/pay-rails/pay") # Automatically retry requests that fail # This automatically includes idempotency keys in the request to guarantee that retires are safe # https://github.com/stripe/stripe-ruby#configuring-automatic-retries ::Stripe.max_network_retries = 2 end |
.signing_secret ⇒ Object
80 81 82 |
# File 'lib/pay/stripe.rb', line 80 def self.signing_secret find_value_by_name(:stripe, :signing_secret) end |
.sync_checkout_session(session_id, stripe_account: nil, try: 0, retries: 5) ⇒ Object
Subscriptions aren't always immediately associated, so we want to retry by default
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/pay/stripe.rb', line 168 def self.sync_checkout_session(session_id, stripe_account: nil, try: 0, retries: 5) checkout_session = ::Stripe::Checkout::Session.retrieve({id: session_id, expand: ["payment_intent.latest_charge"]}, {stripe_account: stripe_account}.compact) case checkout_session.mode when "payment" if (id = checkout_session.payment_intent.try(:latest_charge)&.id) Pay::Stripe::Charge.sync(id, stripe_account: stripe_account, retries: 5) end when "subscription" Pay::Stripe::Subscription.sync(checkout_session.subscription, stripe_account: stripe_account) end rescue ::Stripe::InvalidRequestError if try > retries raise else try += 1 sleep 0.15**try retry end end |
.to_client_reference_id(record) ⇒ Object
148 149 150 151 |
# File 'lib/pay/stripe.rb', line 148 def self.to_client_reference_id(record) raise ArgumentError, "#{record.class.name} does not include Pay. Allowed models: #{model_names.to_a.join(", ")}" unless model_names.include?(record.class.name) [record.class.name, record.id].join("_") end |
.webhook_receive_test_events ⇒ Object
84 85 86 87 |
# File 'lib/pay/stripe.rb', line 84 def self.webhook_receive_test_events value = find_value_by_name(:stripe, :webhook_receive_test_events) value.blank? || ActiveModel::Type::Boolean.new.cast(value) end |