lib/shoppe/stripe.rb in shoppe-stripe-1.1.0 vs lib/shoppe/stripe.rb in shoppe-stripe-1.2.1
- old
+ new
@@ -1,7 +1,7 @@
require 'shoppe/stripe/version'
-require 'shoppe/stripe/railtie'
+require 'shoppe/stripe/engine'
module Shoppe
module Stripe
class << self
@@ -13,52 +13,79 @@
def publishable_key
Shoppe.settings.stripe_publishable_key
end
def setup
+ # Set the configuration which we would like
Shoppe.add_settings_group :stripe, [:stripe_api_key, :stripe_publishable_key, :stripe_currency]
+ # Require the external Stripe library
require 'stripe'
-
+
+ # Extend Shoppe Order & Payment classess
require 'shoppe/stripe/order_extensions'
Shoppe::Order.send :include, Shoppe::Stripe::OrderExtensions
+
+ require 'shoppe/stripe/payment_extensions'
+ Shoppe::Payment.send :include, Shoppe::Stripe::PaymentExtensions
# When an order is confirmed, attempt to authorise the payment
Shoppe::Order.before_confirmation do
if self.properties['stripe_customer_token']
begin
- charge = ::Stripe::Charge.create({:customer => self.properties['stripe_customer_token'], :amount => self.total_in_pence, :currency => Shoppe.settings.stripe_currency, :capture => false}, Shoppe.settings.stripe_api_key)
- self.paid_at = Time.now
- self.payment_method = 'Stripe'
- self.payment_reference = charge.id
+ charge = ::Stripe::Charge.create({:customer => self.properties['stripe_customer_token'], :amount => (self.total * BigDecimal(100)).round, :currency => Shoppe.settings.stripe_currency, :capture => false}, Shoppe.settings.stripe_api_key)
+ self.payments.create(:amount => self.total, :method => 'Stripe', :reference => charge.id, :refundable => true, :confirmed => false)
rescue ::Stripe::CardError
raise Shoppe::Errors::PaymentDeclined, "Payment was declined by the payment processor."
end
end
end
# When an order is accepted, attempt to capture the payment
Shoppe::Order.before_acceptance do
- if stripe_charge
+ self.payments.where(:confirmed => false, :method => 'Stripe').each do |payment|
begin
- stripe_charge.capture
- rescue ::Stripe::Error
- raise Shoppe::Errors::PaymentDeclined, "Payment could not be captured by Stripe. Investigate with Stripe. Do not accept the order."
+ payment.stripe_charge.capture
+ payment.update_attribute(:confirmed, true)
+ rescue ::Stripe::CardError
+ raise Shoppe::Errors::PaymentDeclined, "Payment ##{payment.id} could not be captured by Stripe. Investigate with Stripe. Do not accept the order."
end
end
end
- # When an order is rejected, attempt to refund the payment
+ # When an order is rejected, attempt to refund all the payments which have been
+ # created with Stripe and are not confirmed.
Shoppe::Order.before_rejection do
- if stripe_charge
+ self.payments.where(:confirmed => false, :method => 'Stripe').each do |payment|
+ payment.refund!(payment.refundable_amount)
+ end
+ end
+
+ # When a new payment is added which is a refund and associated with another Stripe method,
+ # attempt to refund it automatically.
+ Shoppe::Payment.before_create do
+ if self.refund? && self.parent && self.parent.method == 'Stripe'
begin
- stripe_charge.refund
- rescue ::Stripe::Error
- raise Shoppe::Errors::PaymentDeclined, "Payment could not be captured by Stripe. Investigate with Stripe. Do not accept the order."
+ options = {}
+ if self.parent.confirmed?
+ options[:amount] = (self.amount * BigDecimal(100)).round.abs
+ else
+ # If the original item hasn't been captured and the amount refunded isn't the
+ # same as the orignal value, raise an error.
+ if self.amount.abs != self.parent.refundable_amount
+ raise Shoppe::Errors::RefundFailed, :message => "Refund could not be processed because charge hasn't been captured and the amount is not the same as the original payment."
+ end
+ end
+ refund = self.parent.stripe_charge.refund(options)
+ self.method = 'Stripe'
+ self.reference = refund.id
+ true
+ rescue ::Stripe::CardError, ::Stripe::InvalidRequestError => e
+ raise Shoppe::Errors::RefundFailed, :message => "Refund could not be processed with Stripe (#{e.class}: #{e.message}). Please investigate with Stripe."
end
end
end
+
end
-
end
end
end