From 8453d5cc03527c22c6414c453f217757ec65017a Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Mon, 25 Jun 2018 18:14:50 +1000 Subject: [PATCH] various --- app/controllers/controllers.rb | 2 + .../discourse_donations/charges_controller.rb | 53 +++++++--- .../payments_controller.rb | 11 --- .../discourse_donations/application_helper.rb | 5 - app/services/discourse_donations/stripe.rb | 67 +++++++++++-- app/services/services.rb | 2 + .../discourse/components/donation-list.js.es6 | 5 + .../discourse/components/stripe-card.js.es6 | 98 +++++++++++++------ .../discourse/controllers/donate.js.es6 | 11 +++ .../discourse/helpers/donation.js.es6 | 56 +++++++++++ .../discourse/lib/donation-utilities.js.es6 | 31 ++++++ .../discourse/routes/donate.js.es6 | 20 ++++ .../templates/components/donation-list.hbs | 23 +++++ .../templates/components/stripe-card.hbs | 15 ++- .../connectors/extra-nav-item/donate.hbs | 6 +- .../discourse/templates/donate.hbs | 21 +++- assets/stylesheets/discourse-donations.scss | 23 ++++- config/locales/client.en.yml | 25 +++-- config/locales/server.en.yml | 5 +- config/routes.rb | 5 +- config/settings.yml | 8 +- lib/discourse_donations/engine.rb | 1 - plugin.rb | 16 +-- 23 files changed, 406 insertions(+), 103 deletions(-) create mode 100644 app/controllers/controllers.rb delete mode 100644 app/controllers/discourse_donations/payments_controller.rb delete mode 100644 app/helpers/discourse_donations/application_helper.rb create mode 100644 app/services/services.rb create mode 100644 assets/javascripts/discourse/components/donation-list.js.es6 create mode 100644 assets/javascripts/discourse/controllers/donate.js.es6 create mode 100644 assets/javascripts/discourse/helpers/donation.js.es6 create mode 100644 assets/javascripts/discourse/lib/donation-utilities.js.es6 create mode 100644 assets/javascripts/discourse/routes/donate.js.es6 create mode 100644 assets/javascripts/discourse/templates/components/donation-list.hbs diff --git a/app/controllers/controllers.rb b/app/controllers/controllers.rb new file mode 100644 index 0000000..d11f590 --- /dev/null +++ b/app/controllers/controllers.rb @@ -0,0 +1,2 @@ +load File.expand_path('../discourse_donations/charges_controller.rb', __FILE__) +load File.expand_path('../discourse_donations/checkout_controller.rb', __FILE__) diff --git a/app/controllers/discourse_donations/charges_controller.rb b/app/controllers/discourse_donations/charges_controller.rb index ba30895..1c79371 100644 --- a/app/controllers/discourse_donations/charges_controller.rb +++ b/app/controllers/discourse_donations/charges_controller.rb @@ -1,11 +1,18 @@ -require_dependency 'discourse' - module DiscourseDonations class ChargesController < ::ApplicationController - skip_before_action :verify_authenticity_token, only: [:create] - skip_before_action :check_xhr - before_action :set_user_and_email, only: [:create] + before_action :set_user, only: [:index, :create] + before_action :set_email, only: [:create] + + def index + if @user && @user.stripe_customer_id + result = DiscourseDonations::Stripe.new(secret_key, stripe_options).list(@user) + else + result = {} + end + + render json: success_json.merge(result) + end def create Rails.logger.info user_params.inspect @@ -30,6 +37,7 @@ module DiscourseDonations Rails.logger.debug "Creating a Stripe payment" payment = DiscourseDonations::Stripe.new(secret_key, stripe_options) + result = {} begin Rails.logger.debug "Creating a Stripe charge for #{user_params[:amount]}" @@ -40,15 +48,17 @@ module DiscourseDonations } if user_params[:type] === 'once' - result = payment.charge(@user, opts) + result[:payment] = payment.charge(@user, opts) else opts[:type] = user_params[:type] - result = payment.subscribe(@user, opts) + result[:subscription] = payment.subscribe(@user, opts) end rescue ::Stripe::CardError => e err = e.json_body[:error] + puts "HERE IS THE ERROR: #{e.inspect}" + output['messages'] << "There was an error (#{err[:type]})." output['messages'] << "Error code: #{err[:code]}" if err[:code] output['messages'] << "Decline code: #{err[:decline_code]}" if err[:decline_code] @@ -57,8 +67,21 @@ module DiscourseDonations render(json: output) && (return) end - if result['paid'] == true || result['status'] === 'active' - output['messages'] << I18n.l(Time.now(), format: :long) + ': ' + I18n.t('donations.payment.success') + if (result[:charge] && result[:charge]['paid'] == true) || + (result[:subscription] && result[:subscription]['status'] === 'active') + + output['messages'] << I18n.t('donations.payment.success') + + if result[:charge] + output['messages'] << " #{I18n.t('donations.payment.receipt_sent', email: @email)}" + end + + if result[:subscription] + output['messages'] << " #{I18n.t('donations.payment.invoice_sent', email: @email)}" + end + + output['charge'] = result[:charge] if result[:charge] + output['subscription'] = result[:subscription] if result[:subscription] output['rewards'] << { type: :group, name: group_name } if group_name output['rewards'] << { type: :badge, name: badge_name } if badge_name @@ -105,23 +128,23 @@ module DiscourseDonations params.permit(:user_id, :name, :username, :email, :password, :stripeToken, :type, :amount, :create_account) end - def email - end - - def set_user_and_email + def set_user user = current_user if user_params[:user_id].present? user = User.find(user_params[:user_id]) end + @user = user + end + + def set_email if user_params[:email].present? email = user_params[:email] else - email = user.try(:email) + email = @user.try(:email) end - @user = user @email = email end end diff --git a/app/controllers/discourse_donations/payments_controller.rb b/app/controllers/discourse_donations/payments_controller.rb deleted file mode 100644 index e4a6c27..0000000 --- a/app/controllers/discourse_donations/payments_controller.rb +++ /dev/null @@ -1,11 +0,0 @@ -module DiscourseDonations - class PaymentsController < ApplicationController - def index - render json: {} - end - - def show - render json: {} - end - end -end diff --git a/app/helpers/discourse_donations/application_helper.rb b/app/helpers/discourse_donations/application_helper.rb deleted file mode 100644 index 9009142..0000000 --- a/app/helpers/discourse_donations/application_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ - -module DiscourseDonations - module ApplicationHelper - end -end diff --git a/app/services/discourse_donations/stripe.rb b/app/services/discourse_donations/stripe.rb index 893d4a2..c43a9cf 100644 --- a/app/services/discourse_donations/stripe.rb +++ b/app/services/discourse_donations/stripe.rb @@ -1,5 +1,3 @@ -RECURRING_DONATION_PRODUCT_ID = 'discourse_donation_recurring' - module DiscourseDonations class Stripe attr_reader :charge, :currency, :description @@ -30,7 +28,8 @@ module DiscourseDonations customer: customer.id, amount: opts[:amount], description: @description, - currency: @currency + currency: @currency, + receipt_email: customer.email ) @charge @@ -56,7 +55,49 @@ module DiscourseDonations @subscription end - def customer(user, email, source) + def list(user) + customer = customer(user) + result = {} + + raw_invoices = ::Stripe::Invoice.list(customer: customer.id) + raw_invoices = raw_invoices.is_a?(Object) ? raw_invoices['data'] : [] + + raw_charges = ::Stripe::Charge.list(customer: customer.id) + raw_charges = raw_charges.is_a?(Object) ? raw_charges['data'] : [] + + if raw_invoices.any? + raw_subscriptions = ::Stripe::Subscription.list(customer: customer.id)['data'] + + if raw_subscriptions.any? + subscriptions = [] + + raw_subscriptions.each do |subscription| + invoices = raw_invoices.select do |invoice| + invoice['subscription'] === subscription['id'] + end + + subscriptions.push( + subscription: subscription, + invoices: invoices + ) + end + + result[:subscriptions] = subscriptions + end + + ## filter out any charges related to subscriptions + raw_invoice_ids = raw_invoices.map { |i| i['id'] } + raw_charges = raw_charges.select { |c| raw_invoice_ids.exclude?(c['invoice']) } + end + + if raw_charges.any? + result[:charges] = raw_charges + end + + result + end + + def customer(user, email = nil, source = nil) if user && user.stripe_customer_id ::Stripe::Customer.retrieve(user.stripe_customer_id) else @@ -84,8 +125,8 @@ module DiscourseDonations products = ::Stripe::Product.list(type: 'service') - if products['data'] && products['data'].any? { |p| p['id'] === RECURRING_DONATION_PRODUCT_ID } - product = RECURRING_DONATION_PRODUCT_ID + if products['data'] && products['data'].any? { |p| p['id'] === product_id } + product = product_id else result = create_product product = result['id'] @@ -94,7 +135,7 @@ module DiscourseDonations ::Stripe::Plan.create( id: id, nickname: nickname, - interval: type.tr('ly', ''), + interval: type, currency: @currency, product: product, amount: amount.to_i @@ -103,12 +144,20 @@ module DiscourseDonations def create_product ::Stripe::Product.create( - id: RECURRING_DONATION_PRODUCT_ID, - name: "Discourse Donation Recurring", + id: product_id, + name: product_name, type: 'service' ) end + def product_id + @product_id ||= "#{SiteSetting.title}_recurring_donation" + end + + def product_name + @product_name ||= I18n.t('discourse_donations.recurring', site_title: SiteSetting.title) + end + def create_plan_id(type) "discourse_donation_recurring_#{type}" end diff --git a/app/services/services.rb b/app/services/services.rb new file mode 100644 index 0000000..8e8aabc --- /dev/null +++ b/app/services/services.rb @@ -0,0 +1,2 @@ +load File.expand_path('../discourse_donations/rewards.rb', __FILE__) +load File.expand_path('../discourse_donations/stripe.rb', __FILE__) diff --git a/assets/javascripts/discourse/components/donation-list.js.es6 b/assets/javascripts/discourse/components/donation-list.js.es6 new file mode 100644 index 0000000..744ebe3 --- /dev/null +++ b/assets/javascripts/discourse/components/donation-list.js.es6 @@ -0,0 +1,5 @@ +export default Ember.Component.extend({ + classNames: 'donation-list', + hasSubscriptions: Ember.computed.notEmpty('subscriptions'), + hasCharges: Ember.computed.notEmpty('charges') +}) diff --git a/assets/javascripts/discourse/components/stripe-card.js.es6 b/assets/javascripts/discourse/components/stripe-card.js.es6 index ca4bc3c..d02b917 100644 --- a/assets/javascripts/discourse/components/stripe-card.js.es6 +++ b/assets/javascripts/discourse/components/stripe-card.js.es6 @@ -1,5 +1,6 @@ import { ajax } from 'discourse/lib/ajax'; import { getRegister } from 'discourse-common/lib/get-owner'; +import { formatAnchor, zeroDecimalCurrencies } from '../lib/donation-utilities'; import { default as computed } from 'ember-addons/ember-computed-decorators'; export default Ember.Component.extend({ @@ -11,12 +12,13 @@ export default Ember.Component.extend({ init() { this._super(); - this.set('anon', (!Discourse.User.current())); - this.set('settings', getRegister(this).lookup('site-settings:main')); - this.set('create_accounts', this.get('anon') && this.get('settings').discourse_donations_enable_create_accounts); - this.set('stripe', Stripe(this.get('settings').discourse_donations_public_key)); + const user = this.get('currentUser'); + const settings = Discourse.SiteSettings; - const types = Discourse.SiteSettings.discourse_donations_types.split('|') || []; + this.set('create_accounts', !user && settings.discourse_donations_enable_create_accounts); + this.set('stripe', Stripe(settings.discourse_donations_public_key)); + + const types = settings.discourse_donations_types.split('|') || []; const amounts = this.get('donateAmounts'); this.setProperties({ @@ -38,21 +40,7 @@ export default Ember.Component.extend({ @computed('type') period(type) { - let anchor; - - if (type === 'weekly') { - anchor = moment().format('dddd'); - } - - if (type === 'monthly') { - anchor = moment().format('Do'); - } - - if (type === 'yearly') { - anchor = moment().format('MMMM D'); - } - - return I18n.t(`discourse_donations.period.${type}`, { anchor }); + return I18n.t(`discourse_donations.period.${type}`, { anchor: formatAnchor(type) }); }, @computed @@ -73,9 +61,23 @@ export default Ember.Component.extend({ @computed('stripe') card(stripe) { let elements = stripe.elements(); - return elements.create('card', { - hidePostalCode: !this.get('settings').discourse_donations_zip_code + let card = elements.create('card', { + hidePostalCode: !Discourse.SiteSettings.discourse_donations_zip_code }); + + card.addEventListener('change', (event) => { + if (event.error) { + this.set('stripeError', event.error.message); + } else { + this.set('stripeError', ''); + } + + if (event.elementType === 'card' && event.complete) { + this.set('stripeReady', true); + } + }); + + return card; }, @computed('amount') @@ -92,6 +94,21 @@ export default Ember.Component.extend({ return amount; }, + @computed('currentUser', 'email') + userReady(currentUser, email) { + return currentUser || email; + }, + + @computed('userReady', 'stripeReady') + formIncomplete(userReady, stripeReady) { + return !userReady || !stripeReady; + }, + + @computed('transactionInProgress', 'formIncomplete') + disableSubmit(transactionInProgress, formIncomplete) { + return transactionInProgress || formIncomplete; + }, + didInsertElement() { this._super(); this.get('card').mount('#card-element'); @@ -130,27 +147,52 @@ export default Ember.Component.extend({ submitStripeCard() { let self = this; - self.set('transactionInProgress', true); + this.set('transactionInProgress', true); + this.get('stripe').createToken(this.get('card')).then(data => { self.set('result', []); if (data.error) { - self.set('result', data.error.message); + this.setProperties({ + stripeError: data.error.message, + stripeReady: false + }); self.endTranscation(); } else { - const transactionFeeEnabled = Discourse.SiteSettings.discourse_donations_enable_transaction_fee; - const amount = transactionFeeEnabled ? this.get('totalAmount') : this.get('amount'); + const settings = Discourse.SiteSettings; + + const transactionFeeEnabled = settings.discourse_donations_enable_transaction_fee; + let amount = transactionFeeEnabled ? this.get('totalAmount') : this.get('amount'); + + if (zeroDecimalCurrencies.indexOf(setting.discourse_donations_currency) === -1) { + amount = amount * 100; + } + let params = { stripeToken: data.token.id, type: self.get('type'), - amount: amount * 100, + amount, 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(d => { + ajax('/donate/charges', { data: params, method: 'post' }).then(d => { + let donation = d.donation; + + if (donation) { + if (donation.object === 'subscription') { + let subscriptions = this.get('subscriptions') || []; + subscriptions.push(donation); + this.set('subscriptions', subscriptions); + } else if (donation.object === 'charge') { + let charges = this.get('charges') || []; + charges.push(donation); + this.set('charges', charges); + } + } + self.concatMessages(d.messages); self.endTranscation(); }); diff --git a/assets/javascripts/discourse/controllers/donate.js.es6 b/assets/javascripts/discourse/controllers/donate.js.es6 new file mode 100644 index 0000000..daecc05 --- /dev/null +++ b/assets/javascripts/discourse/controllers/donate.js.es6 @@ -0,0 +1,11 @@ +import { default as computed } from 'ember-addons/ember-computed-decorators'; + +export default Ember.Controller.extend({ + loadingDonations: false, + + @computed('charges', 'subscriptions') + hasDonations(charges, subscriptions) { + return (charges && charges.length > 0) || + (subscriptions && subscriptions.length > 0); + } +}) diff --git a/assets/javascripts/discourse/helpers/donation.js.es6 b/assets/javascripts/discourse/helpers/donation.js.es6 new file mode 100644 index 0000000..cd372c5 --- /dev/null +++ b/assets/javascripts/discourse/helpers/donation.js.es6 @@ -0,0 +1,56 @@ +import { registerHelper } from "discourse-common/lib/helpers"; +import { formatAnchor, formatAmount } from '../lib/donation-utilities'; + +registerHelper("donation-subscription", function([subscription]) { + let currency = subscription.plan.currency.toUpperCase(); + let html = currency; + + html += ` ${formatAmount(subscription.plan.amount, currency)} `; + + html += I18n.t(`discourse_donations.period.${subscription.plan.interval}`, { + anchor: formatAnchor(subscription.plan.interval, moment.unix(subscription.billing_cycle_anchor)) + }); + + return new Handlebars.SafeString(html); +}); + +registerHelper("donation-invoice", function([invoice]) { + let details = invoice.lines.data[0]; + let html = I18n.t('discourse_donations.invoice_prefix'); + let currency = details.currency.toUpperCase(); + + html += ` ${currency}`; + + html += ` ${formatAmount(details.amount, currency)} `; + + html += I18n.t(`discourse_donations.period.once`, { + anchor: formatAnchor('once', moment.unix(invoice.date)) + }); + + if (invoice.invoice_pdf) { + html += ` (${I18n.t('discourse_donations.invoice')})`; + } + + return new Handlebars.SafeString(html); +}); + +registerHelper("donation-charge", function([charge]) { + let html = I18n.t('discourse_donations.invoice_prefix'); + let currency = charge.currency.toUpperCase(); + + html += ` ${currency}`; + + html += ` ${formatAmount(charge.amount, currency)} `; + + html += I18n.t(`discourse_donations.period.once`, { + anchor: formatAnchor('once', moment.unix(charge.created)) + }); + + if (charge.receipt_email) { + html += `. ${I18n.t('discourse_donations.receipt', { + email: charge.receipt_email + })}`; + } + + return new Handlebars.SafeString(html); +}); diff --git a/assets/javascripts/discourse/lib/donation-utilities.js.es6 b/assets/javascripts/discourse/lib/donation-utilities.js.es6 new file mode 100644 index 0000000..6f82bf2 --- /dev/null +++ b/assets/javascripts/discourse/lib/donation-utilities.js.es6 @@ -0,0 +1,31 @@ +const formatAnchor = function(type = null, time = moment()) { + let format; + + switch(type) { + case 'once': + format = 'Do MMMM YYYY'; + break; + case 'week': + format = 'dddd'; + break; + case 'month': + format = 'Do'; + break; + case 'year': + format = 'MMMM D'; + break; + default: + format = 'dddd'; + } + + return moment(time).format(format); +} + +const zeroDecimalCurrencies = ['MGA', 'BIF', 'CLP', 'PYG', 'DFJ', 'RWF', 'GNF', 'UGX', 'JPY', 'VND', 'VUV', 'XAF', 'KMF', 'KRW', 'XOF', 'XPF']; + +const formatAmount = function(amount, currency) { + let zeroDecimal = zeroDecimalCurrencies.indexOf(currency) > -1; + return zeroDecimal ? amount : (amount / 100).toFixed(2); +} + +export { formatAnchor, formatAmount, zeroDecimalCurrencies } diff --git a/assets/javascripts/discourse/routes/donate.js.es6 b/assets/javascripts/discourse/routes/donate.js.es6 new file mode 100644 index 0000000..90b12e0 --- /dev/null +++ b/assets/javascripts/discourse/routes/donate.js.es6 @@ -0,0 +1,20 @@ +import DiscourseRoute from "discourse/routes/discourse"; +import { popupAjaxError } from 'discourse/lib/ajax-error'; +import { ajax } from 'discourse/lib/ajax'; + +export default DiscourseRoute.extend({ + setupController(controller) { + controller.set('loadingDonations', true); + + ajax('/donate/charges').then((result) => { + if (result && (result.charges || result.subscriptions)) { + controller.setProperties({ + charges: result.charges, + subscriptions: result.subscriptions + }); + } + }).catch(popupAjaxError).finally(() => { + controller.set('loadingDonations', false); + }) + } +}); diff --git a/assets/javascripts/discourse/templates/components/donation-list.hbs b/assets/javascripts/discourse/templates/components/donation-list.hbs new file mode 100644 index 0000000..fba86c4 --- /dev/null +++ b/assets/javascripts/discourse/templates/components/donation-list.hbs @@ -0,0 +1,23 @@ +{{#if hasCharges}} +

{{i18n 'discourse_donations.donations.charges'}}

+ +{{/if}} + +{{#if hasSubscriptions}} +

{{i18n 'discourse_donations.donations.subscriptions'}}

+ +{{/if}} diff --git a/assets/javascripts/discourse/templates/components/stripe-card.hbs b/assets/javascripts/discourse/templates/components/stripe-card.hbs index 7b3fc3b..e1ffa1e 100644 --- a/assets/javascripts/discourse/templates/components/stripe-card.hbs +++ b/assets/javascripts/discourse/templates/components/stripe-card.hbs @@ -1,5 +1,4 @@
-
{{/if}} - {{/if}} + {{/unless}}
- {{#d-button action="submitStripeCard" disabled=transactionInProgress class="btn btn-primary btn-payment"}} + {{#d-button action="submitStripeCard" disabled=disableSubmit class="btn btn-primary btn-payment"}} {{#if create_accounts}} {{i18n 'discourse_donations.submit_with_create_account'}} {{else}} diff --git a/assets/javascripts/discourse/templates/connectors/extra-nav-item/donate.hbs b/assets/javascripts/discourse/templates/connectors/extra-nav-item/donate.hbs index 1f57cc3..69bb4ec 100644 --- a/assets/javascripts/discourse/templates/connectors/extra-nav-item/donate.hbs +++ b/assets/javascripts/discourse/templates/connectors/extra-nav-item/donate.hbs @@ -1,5 +1,5 @@ {{#if siteSettings.discourse_donations_enabled}} - - {{i18n 'discourse_donations.nav_item'}} - + + {{i18n 'discourse_donations.nav_item'}} + {{/if}} diff --git a/assets/javascripts/discourse/templates/donate.hbs b/assets/javascripts/discourse/templates/donate.hbs index 0dccb22..42a804b 100644 --- a/assets/javascripts/discourse/templates/donate.hbs +++ b/assets/javascripts/discourse/templates/donate.hbs @@ -1,7 +1,24 @@ -

{{i18n 'discourse_donations.title' site_name=siteSettings.title}}

+

{{i18n 'discourse_donations.title' site_name=siteSettings.title}}

+
{{cook-text siteSettings.discourse_donations_page_description}}
+
- {{stripe-card}} + {{stripe-card charges=charges subscriptions=subscriptions}}
+ +{{#if currentUser}} +
+

{{i18n 'discourse_donations.donations.title'}}

+ {{#if loadingDonations}} + {{loading-spinner size='small'}} + {{else}} + {{#if hasDonations}} + {{donation-list charges=charges subscriptions=subscriptions}} + {{else}} + {{i18n 'discourse_donations.donations.none'}} + {{/if}} + {{/if}} +
+{{/if}} diff --git a/assets/stylesheets/discourse-donations.scss b/assets/stylesheets/discourse-donations.scss index 50f5927..23c0263 100644 --- a/assets/stylesheets/discourse-donations.scss +++ b/assets/stylesheets/discourse-donations.scss @@ -13,7 +13,7 @@ div.stripe-errors { } .donations-page-payment { - padding-top: 60px; + padding: 30px 0; #payment-form { .control-label { @@ -27,6 +27,11 @@ div.stripe-errors { input[type="checkbox"] { margin: 0; } + + .stripe-error { + margin-top: 5px; + color: $danger; + } } } @@ -49,3 +54,19 @@ div.stripe-errors { width: 400px; z-index: 1; } + +.body-page .donations-page-donations { + margin-bottom: 40px; + + .donation-list { + ul { + margin-left: 0; + list-style: none; + + li.underline { + border-bottom: 1px solid $primary-medium; + display: inline-block; + } + } + } +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index e85a01a..657b3de 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -23,12 +23,16 @@ en: js: discourse_donations: - title: Donate nav_item: Donate + title: "Make a Donation" amount: Amount card: Card submit: Make Payment submit_with_create_account: Make Payment and Create Account + invoice: "Invoice" + invoice_prefix: "You gave" + receipt: "Receipt sent to {{email}}." + email_instructions: "Required to send you a receipt. Not used for marketing." transaction_fee: label: "Include transaction fee of {{currency}} {{transactionFee}}" description: "When you make a donation we get charged a transaction fee. If you would like to help us out with this fee, check this box and it will be included in your donation." @@ -38,11 +42,16 @@ en: type: "Type" types: once: "Once" - weekly: "Weekly" - monthly: "Monthly" - yearly: "Yearly" + week: "Weekly" + month: "Monthly" + year: "Yearly" period: - once: "once." - weekly: "every week on {{anchor}}." - monthly: "on the {{anchor}} of every month." - yearly: "every year on {{anchor}}." + once: "on {{anchor}}" + week: "every week on {{anchor}}" + month: "on the {{anchor}} of every month" + year: "every year on {{anchor}}" + donations: + title: "Your Donations" + charges: "Once Off" + subscriptions: "Recurring" + none: "You haven't made a donation yet." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index dc63d40..9b59074 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1,4 +1,7 @@ en: donations: + recurring: "%{site_title} recurring donation" payment: - success: 'Thank you. Your donation has been successful' + success: 'Thank you, your donation has been successful.' + receipt_sent: 'A receipt has been sent to %{email}.' + invoice_sent: 'An invoice has been sent to %{email}.' diff --git a/config/routes.rb b/config/routes.rb index eba16d8..c17ffdd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,5 @@ DiscourseDonations::Engine.routes.draw do - resources :charges, only: [:create] + get '/' => 'charges#index' + resources :charges, only: [:index, :create] resources :checkout, only: [:create] - get 'users/:username/payments' => 'payments#show' - get 'donate' => 'payments#show' end diff --git a/config/settings.yml b/config/settings.yml index 066f016..ac439b2 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -53,9 +53,9 @@ plugins: discourse_donations_types: client: true type: list - default: 'monthly|once' + default: 'month|once' choices: - - yearly - - monthly - - weekly + - year + - month + - week - once diff --git a/lib/discourse_donations/engine.rb b/lib/discourse_donations/engine.rb index c743474..d92e065 100644 --- a/lib/discourse_donations/engine.rb +++ b/lib/discourse_donations/engine.rb @@ -1,4 +1,3 @@ - module ::DiscourseDonations class Engine < ::Rails::Engine engine_name 'discourse-donations' diff --git a/plugin.rb b/plugin.rb index 9f6715d..514fd5e 100644 --- a/plugin.rb +++ b/plugin.rb @@ -2,12 +2,10 @@ # about: Integrates Stripe into Discourse to allow forum visitors to make donations # version: 1.11.1 # url: https://github.com/chrisbeach/discourse-donations -# authors: Rimian Perkins, Chris Beach +# authors: Rimian Perkins, Chris Beach, Angus McLeod gem 'stripe', '2.8.0' -load File.expand_path('../lib/discourse_donations/engine.rb', __FILE__) - register_asset "stylesheets/discourse-donations.scss" enabled_site_setting :discourse_donations_enabled @@ -17,7 +15,15 @@ register_html_builder('server:before-head-close') do end after_initialize do + load File.expand_path('../lib/discourse_donations/engine.rb', __FILE__) + load File.expand_path('../config/routes.rb', __FILE__) + load File.expand_path('../app/controllers/controllers.rb', __FILE__) load File.expand_path('../app/jobs/jobs.rb', __FILE__) + load File.expand_path('../app/services/services.rb', __FILE__) + + Discourse::Application.routes.append do + mount ::DiscourseDonations::Engine, at: 'donate' + end class ::User def stripe_customer_id @@ -29,7 +35,3 @@ after_initialize do end end end - -Discourse::Application.routes.prepend do - mount ::DiscourseDonations::Engine, at: '/' -end