diff --git a/app/controllers/discourse_donations/charges_controller.rb b/app/controllers/discourse_donations/charges_controller.rb index ff6c266..7563474 100644 --- a/app/controllers/discourse_donations/charges_controller.rb +++ b/app/controllers/discourse_donations/charges_controller.rb @@ -24,7 +24,7 @@ module DiscourseDonations end if output['messages'].present? - render(:json => output.merge(success: false)) and return + render(json: output.merge(success: false)) && (return) end Rails.logger.debug "Creating a Stripe payment" @@ -32,7 +32,15 @@ module DiscourseDonations begin Rails.logger.debug "Creating a Stripe charge for #{user_params[:amount]}" - charge = payment.charge(email, user_params[:stripeToken], user_params[:amount]) + charge_params = [user_params[:stripeToken], user_params[:amount]] + + if user + charge_params.unshift(user, user.email) + else + charge_params.unshift(nil, email) + end + + charge = payment.charge(*charge_params) rescue ::Stripe::CardError => e err = e.json_body[:error] @@ -41,7 +49,7 @@ module DiscourseDonations output['messages'] << "Decline code: #{err[:decline_code]}" if err[:decline_code] output['messages'] << "Message: #{err[:message]}" if err[:message] - render(:json => output) and return + render(json: output) && (return) end if charge['paid'] == true @@ -56,7 +64,7 @@ module DiscourseDonations end end - render :json => output + render json: output end private @@ -89,11 +97,19 @@ module DiscourseDonations end def user_params - params.permit(:name, :username, :email, :password, :stripeToken, :amount, :create_account) + params.permit(:user_id, :name, :username, :email, :password, :stripeToken, :amount, :create_account) end def email - user_params[:email] || current_user.try(:email) + user_params[:email] || user.try(:email) + end + + def user + if user_params[:user_id] + User.find(user_params[:user_id]) + else + current_user + end end end end diff --git a/app/controllers/discourse_donations/checkout_controller.rb b/app/controllers/discourse_donations/checkout_controller.rb index a7d742c..946729c 100644 --- a/app/controllers/discourse_donations/checkout_controller.rb +++ b/app/controllers/discourse_donations/checkout_controller.rb @@ -11,11 +11,10 @@ module DiscourseDonations output = { 'messages' => [], 'rewards' => [] } payment = DiscourseDonations::Stripe.new(secret_key, stripe_options) + user = current_user || nil begin - charge = payment.checkoutCharge(user_params[:stripeEmail], - user_params[:stripeToken], - user_params[:amount]) + charge = payment.checkoutCharge(user, user_params[:stripeEmail], user_params[:stripeToken], user_params[:amount]) rescue ::Stripe::CardError => e err = e.json_body[:error] @@ -24,7 +23,7 @@ module DiscourseDonations output['messages'] << "Decline code: #{err[:decline_code]}" if err[:decline_code] output['messages'] << "Message: #{err[:message]}" if err[:message] - render(:json => output) and return + render(json: output) && (return) end if charge['paid'] @@ -33,12 +32,11 @@ module DiscourseDonations output['rewards'] << { type: :badge, name: badge_name } if badge_name end - render :json => output + render json: output end private - def reward?(payment) payment.present? && payment.successful? end @@ -61,6 +59,7 @@ module DiscourseDonations :stripeToken, :stripeTokenType, :stripeEmail, + :stripeCustomerId, :stripeBillingName, :stripeBillingAddressLine1, :stripeBillingAddressZip, @@ -75,7 +74,6 @@ module DiscourseDonations :stripeShippingAddressCity, :stripeShippingAddressCountry, :stripeShippingAddressCountryCode - ) end diff --git a/app/services/discourse_donations/stripe.rb b/app/services/discourse_donations/stripe.rb index 5283453..936fcb7 100644 --- a/app/services/discourse_donations/stripe.rb +++ b/app/services/discourse_donations/stripe.rb @@ -8,26 +8,19 @@ module DiscourseDonations @currency = opts[:currency] end - def checkoutCharge(email, token, amount) - customer = ::Stripe::Customer.create( - :email => email, - :source => token - ) - + def checkoutCharge(user = nil, email, token, amount) + customer = customer(user, email, token) charge = ::Stripe::Charge.create( - :customer => customer.id, - :amount => amount, - :description => @description, - :currency => @currency + customer: customer.id, + amount: amount, + description: @description, + currency: @currency ) charge end - def charge(email, token, amount) - customer = ::Stripe::Customer.create( - email: email, - source: token - ) + def charge(user = nil, email, token, amount) + customer = customer(user, email, token) @charge = ::Stripe::Charge.create( customer: customer.id, amount: amount, @@ -37,11 +30,8 @@ module DiscourseDonations @charge end - def subscribe(email, opts) - customer = ::Stripe::Customer.create( - email: email, - source: opts[:stripeToken] - ) + def subscribe(user = nil, email, opts) + customer = customer(user, email, opts[:stripeToken]) @subscription = ::Stripe::Subscription.create( customer: customer.id, plan: opts[:plan] @@ -49,6 +39,22 @@ module DiscourseDonations @subscription end + def customer(user, email, source) + if user && user.stripe_customer_id + ::Stripe::Customer.retrieve(user.stripe_customer_id) + else + customer = ::Stripe::Customer.create( + email: email, + source: source + ) + if user + user.custom_fields['stripe_customer_id'] = customer.id + user.save_custom_fields(true) + end + customer + end + end + def successful? @charge[:paid] end diff --git a/assets/javascripts/discourse/components/stripe-card.js.es6 b/assets/javascripts/discourse/components/stripe-card.js.es6 index cd88cc3..029509b 100644 --- a/assets/javascripts/discourse/components/stripe-card.js.es6 +++ b/assets/javascripts/discourse/components/stripe-card.js.es6 @@ -63,18 +63,18 @@ export default Ember.Component.extend({ self.endTranscation(); } else { - let params = { stripeToken: data.token.id, amount: self.get('amount') * 100, + user_id: self.get('currentUser.id'), email: self.get('email'), username: self.get('username'), create_account: self.get('create_accounts') }; if(!self.get('paymentSuccess')) { - ajax('/charges', { data: params, method: 'post' }).then(data => { - self.concatMessages(data.messages); + ajax('/charges', { data: params, method: 'post' }).then(d => { + self.concatMessages(d.messages); self.endTranscation(); }); } diff --git a/plugin.rb b/plugin.rb index e556726..473ac1b 100644 --- a/plugin.rb +++ b/plugin.rb @@ -18,6 +18,16 @@ end after_initialize do load File.expand_path('../app/jobs/jobs.rb', __FILE__) + + class ::User + def stripe_customer_id + if custom_fields['stripe_customer_id'] + custom_fields['stripe_customer_id'] + else + nil + end + end + end end Discourse::Application.routes.prepend do diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb deleted file mode 100644 index e69de29..0000000 diff --git a/spec/services/discourse_donations/stripe_spec.rb b/spec/services/discourse_donations/stripe_spec.rb index 550a47e..d5d795a 100644 --- a/spec/services/discourse_donations/stripe_spec.rb +++ b/spec/services/discourse_donations/stripe_spec.rb @@ -44,12 +44,10 @@ module DiscourseDonations description: stripe_options[:description], currency: stripe_options[:currency] ).returns( - { - paid: true, - outcome: { seller_message: 'yay!' } - } + paid: true, + outcome: { seller_message: 'yay!' } ) - subject.charge(email, params[:stripeToken], params[:amount]) + subject.charge(nil, email, params[:stripeToken], params[:amount]) end end @@ -62,14 +60,14 @@ module DiscourseDonations end it 'is successful' do - ::Stripe::Charge.expects(:create).with(charge_options).returns({paid: true}) - subject.charge(email, params[:stripeToken], params[:amount]) + ::Stripe::Charge.expects(:create).with(charge_options).returns(paid: true) + subject.charge(nil, email, params[:stripeToken], params[:amount]) expect(subject).to be_successful end it 'is not successful' do - ::Stripe::Charge.expects(:create).with(charge_options).returns({paid: false}) - subject.charge(email, params[:stripeToken], params[:amount]) + ::Stripe::Charge.expects(:create).with(charge_options).returns(paid: false) + subject.charge(nil, email, params[:stripeToken], params[:amount]) expect(subject).not_to be_successful end end