Save and reuse stripe customer id when user is present

This commit is contained in:
Angus McLeod 2018-02-02 16:06:43 +08:00
parent dd7e86930f
commit ccf7f1b73b
7 changed files with 73 additions and 45 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
});
}

View File

@ -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

View File

View File

@ -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