diff --git a/README.md b/README.md
deleted file mode 100644
index a01b4ff..0000000
--- a/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# Discourse Donations
-
-[](https://travis-ci.org/rimian/discourse-donations)
-
-Accept donations from visitors to your [Discourse](https://www.discourse.org/) application. Integrates with [Stripe](https://stripe.com).
-
-## Installation
-
-* Be sure your site is enforcing https.
-* Follow the install instructions here: https://meta.discourse.org/t/install-a-plugin/19157
-* Add your Stripe public and private keys in settings and set the currency to your local value.
-* Enable the plugin and wait for people to donate money.
-
-## Usage
-
-1. Click **Donate**:
-
-
-1. Enter card details:
-
-
-1. Click **Make Payment**:
-
-
-## Creating new user accounts
-
-**This is an experimental feature.** A user can create a new account if they makes a successful donation. Enable this in settings. When a user is not logged in, they will be asked to enter details for a new user account. This feature doesn't support mandatory custom user fields yet.
-
-## Testing
-
-These commands should run:
-
-* ```yarn prettier --list-different 'assets/**/*.scss' '**/*.es6'```
-
-## Tested Credit Card Numbers
-
-These numbers can be used in test mode to simulate a transaction. For more information see the [Stripe docs](https://stripe.com/docs/testing).
-
-Card numbers in **bold** have been tested.
-
-* **4000 0000 0000 0077** Charge succeeds and funds will be added directly to your available balance (bypassing your pending balance).
-* **4000 0000 0000 0093** Charge succeeds and domestic pricing is used (other test cards use international pricing). This card is only significant in countries with split pricing.
-* **4000 0000 0000 0010** The address_line1_check and address_zip_check verifications fail. If your account is blocking payments that fail postal code validation, the charge is declined.
-* **4000 0000 0000 0028** Charge succeeds but the address_line1_check verification fails.
-* **4000 0000 0000 0036** The address_zip_check verification fails. If your account is blocking payments that fail postal code validation, the charge is declined.
-* **4000 0000 0000 0044** Charge succeeds but the address_zip_check and address_line1_check verifications are both unavailable.
-* **4000 0000 0000 0101** If a CVC number is provided, the cvc_check fails. If your account is blocking payments that fail CVC code validation, the charge is declined.
-* **4000 0000 0000 0341** Attaching this card to a Customer object succeeds, but attempts to charge the customer fail.
-* **4000 0000 0000 9235** Charge succeeds with a risk_level of elevated and placed into review.
-* **4000 0000 0000 0002** Charge is declined with a card_declined code.
-* **4100 0000 0000 0019** Charge is declined with a card_declined code and a fraudulent reason.
-* **4000 0000 0000 0127** Charge is declined with an incorrect_cvc code.
-* **4000 0000 0000 0069** Charge is declined with an expired_card code.
-* **4000 0000 0000 0119** Charge is declined with a processing_error code.
-* **4242 4242 4242 4241** Charge is declined with an incorrect_number code as the card number fails the Luhn check.
-
-## Warranty
-
-This software comes with no warranty of any kind.
diff --git a/app/controllers/controllers.rb b/app/controllers/controllers.rb
deleted file mode 100644
index 46b553e..0000000
--- a/app/controllers/controllers.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-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
deleted file mode 100644
index d182ce0..0000000
--- a/app/controllers/discourse_donations/charges_controller.rb
+++ /dev/null
@@ -1,190 +0,0 @@
-# frozen_string_literal: true
-
-module DiscourseDonations
- class ChargesController < ::ApplicationController
- skip_before_action :verify_authenticity_token, only: [:create]
-
- before_action :ensure_logged_in, only: [:cancel_subscription]
- before_action :set_user, only: [:index, :create]
- before_action :set_email, only: [:index, :create, :cancel_subscription]
-
- def index
- result = {}
-
- if current_user
- stripe = DiscourseDonations::Stripe.new(secret_key, stripe_options)
-
- list_result = stripe.list(current_user, email: current_user.email)
-
- result = list_result if list_result.present?
- end
-
- render json: success_json.merge(result)
- end
-
- def create
- Rails.logger.info user_params.inspect
-
- output = { 'messages' => [], 'rewards' => [] }
-
- if create_account
- if !@email.present? || !user_params[:username].present?
- output['messages'] << I18n.t('login.missing_user_field')
- end
- if user_params[:password] && user_params[:password].length > User.max_password_length
- output['messages'] << I18n.t('login.password_too_long')
- end
- if user_params[:username] && ::User.reserved_username?(user_params[:username])
- output['messages'] << I18n.t('login.reserved_username')
- end
- end
-
- if output['messages'].present?
- render(json: output.merge(success: false)) && (return)
- end
-
- Rails.logger.debug "Creating a Stripe payment"
- stripe = DiscourseDonations::Stripe.new(secret_key, stripe_options)
- result = {}
-
- begin
- Rails.logger.debug "Creating a Stripe charge for #{user_params[:amount]}"
- opts = {
- cause: user_params[:cause],
- email: @email,
- token: user_params[:stripeToken],
- amount: user_params[:amount]
- }
-
- if user_params[:type] === 'once'
- result[:charge] = stripe.charge(@user, opts)
- else
- opts[:type] = user_params[:type]
-
- subscription = stripe.subscribe(@user, opts)
-
- if subscription && subscription['id']
- invoices = stripe.invoices_for_subscription(@user,
- email: opts[:email],
- subscription_id: subscription['id']
- )
- end
-
- result[:subscription] = {}
- result[:subscription][:subscription] = subscription if subscription
- result[:subscription][:invoices] = invoices if invoices
- end
-
- rescue ::Stripe::CardError => e
- err = e.json_body[:error]
-
- 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]
- output['messages'] << "Message: #{err[:message]}" if err[:message]
-
- render(json: output) && (return)
- end
-
- if (result[:charge] && result[:charge]['paid'] == true) ||
- (result[:subscription] && result[:subscription][:subscription] &&
- result[:subscription][:subscription]['status'] === 'active')
-
- output['messages'] << I18n.t('donations.payment.success')
-
- if (result[:charge] && result[:charge]['receipt_number']) ||
- (result[:subscription] && result[:subscription][:invoices].first['receipt_number'])
- output['messages'] << " #{I18n.t('donations.payment.receipt_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
-
- if create_account && @email.present?
- args = user_params.to_h.slice(:email, :username, :password, :name).merge(rewards: output['rewards'])
- Jobs.enqueue(:donation_user, args)
- end
-
- if SiteSetting.discourse_donations_cause_category
- Jobs.enqueue(:update_category_donation_statistics)
- end
- end
-
- render json: output
- end
-
- def cancel_subscription
- params.require(:subscription_id)
-
- stripe = DiscourseDonations::Stripe.new(secret_key, stripe_options)
-
- result = stripe.cancel_subscription(params[:subscription_id])
-
- if result[:success]
- render json: success_json.merge(subscription: result[:subscription])
- else
- render json: failed_json.merge(message: result[:message])
- end
- end
-
- private
-
- def create_account
- user_params[:create_account] == 'true' && SiteSetting.discourse_donations_enable_create_accounts
- end
-
- def reward?(payment)
- payment.present? && payment.successful?
- end
-
- def group_name
- SiteSetting.discourse_donations_reward_group_name
- end
-
- def badge_name
- SiteSetting.discourse_donations_reward_badge_name
- end
-
- def secret_key
- SiteSetting.discourse_donations_secret_key
- end
-
- def stripe_options
- {
- description: SiteSetting.discourse_donations_description,
- currency: SiteSetting.discourse_donations_currency
- }
- end
-
- def user_params
- params.permit(:user_id, :name, :username, :email, :password, :stripeToken, :cause, :type, :amount, :create_account)
- end
-
- def set_user
- user = current_user
-
- if user_params[:user_id].present?
- if record = User.find_by(user_params[:user_id])
- user = record
- end
- end
-
- @user = user
- end
-
- def set_email
- email = nil
-
- if user_params[:email].present?
- email = user_params[:email]
- elsif @user
- email = @user.try(:email)
- end
-
- @email = email
- end
- end
-end
diff --git a/app/controllers/discourse_donations/checkout_controller.rb b/app/controllers/discourse_donations/checkout_controller.rb
deleted file mode 100644
index 24206e1..0000000
--- a/app/controllers/discourse_donations/checkout_controller.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-# frozen_string_literal: true
-
-require_dependency 'discourse'
-
-module DiscourseDonations
- class CheckoutController < ApplicationController
-
- skip_before_action :verify_authenticity_token, only: [:create]
-
- def create
- Rails.logger.debug params.inspect
- Rails.logger.debug user_params.inspect
-
- output = { 'messages' => [], 'rewards' => [] }
- payment = DiscourseDonations::Stripe.new(secret_key, stripe_options)
- user = current_user || nil
-
- begin
- charge = payment.checkoutCharge(user, user_params[:stripeEmail], user_params[:stripeToken], user_params[:amount])
- rescue ::Stripe::CardError => e
- err = e.json_body[:error]
-
- 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]
- output['messages'] << "Message: #{err[:message]}" if err[:message]
-
- render(json: output) && (return)
- end
-
- if charge['paid']
- output['messages'] << I18n.l(Time.now(), format: :long) + ': ' + I18n.t('donations.payment.success')
- output['rewards'] << { type: :group, name: group_name } if group_name
- output['rewards'] << { type: :badge, name: badge_name } if badge_name
- end
-
- render json: output
- end
-
- private
-
- def reward?(payment)
- payment.present? && payment.successful?
- end
-
- def group_name
- SiteSetting.discourse_donations_reward_group_name
- end
-
- def badge_name
- SiteSetting.discourse_donations_reward_badge_name
- end
-
- def secret_key
- SiteSetting.discourse_donations_secret_key
- end
-
- def user_params
- params.permit(:amount,
- :email,
- :stripeToken,
- :stripeTokenType,
- :stripeEmail,
- :stripeCustomerId,
- :stripeBillingName,
- :stripeBillingAddressLine1,
- :stripeBillingAddressZip,
- :stripeBillingAddressState,
- :stripeBillingAddressCity,
- :stripeBillingAddressCountry,
- :stripeBillingAddressCountryCode,
- :stripeShippingName,
- :stripeShippingAddressLine1,
- :stripeShippingAddressZip,
- :stripeShippingAddressState,
- :stripeShippingAddressCity,
- :stripeShippingAddressCountry,
- :stripeShippingAddressCountryCode
- )
- end
-
- def stripe_options
- {
- description: SiteSetting.discourse_donations_description,
- currency: SiteSetting.discourse_donations_currency
- }
- end
- end
-end
diff --git a/app/jobs/jobs.rb b/app/jobs/jobs.rb
deleted file mode 100644
index 5c38931..0000000
--- a/app/jobs/jobs.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-load File.expand_path('../regular/donation_user.rb', __FILE__)
-load File.expand_path('../scheduled/update_category_donation_statistics.rb', __FILE__)
diff --git a/app/jobs/regular/donation_user.rb b/app/jobs/regular/donation_user.rb
deleted file mode 100644
index 88ea75d..0000000
--- a/app/jobs/regular/donation_user.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module Jobs
- class DonationUser < ::Jobs::Base
- def execute(args)
- user = User.create!(args.slice(:username, :password, :name, :email))
- return unless user.persisted?
- Jobs.enqueue(
- :critical_user_email,
- type: :signup, user_id: user.id, email_token: user.email_tokens.first.token
- )
- rewards = DiscourseDonations::Rewards.new(user)
- args[:rewards].to_a.each do |reward|
- rewards.grant_badge(reward[:name]) if reward[:type] == 'badge'
- rewards.add_to_group(reward[:name]) if reward[:type] == 'group'
- end
- end
- end
-end
diff --git a/app/jobs/scheduled/update_category_donation_statistics.rb b/app/jobs/scheduled/update_category_donation_statistics.rb
deleted file mode 100644
index 5046656..0000000
--- a/app/jobs/scheduled/update_category_donation_statistics.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-module Jobs
- class UpdateCategoryDonationStatistics < ::Jobs::Scheduled
- every 1.day
-
- def execute(args)
- return unless SiteSetting.discourse_donations_cause_category
-
- ::Stripe.api_key = SiteSetting.discourse_donations_secret_key
- totals = {}
- backers = {}
- categories = []
-
- raw_charges = ::Stripe::Charge.list(
- expand: ['data.invoice.subscription', 'data.customer']
- )
- raw_charges = raw_charges.is_a?(Object) ? raw_charges['data'] : []
-
- raw_charges.each do |c|
- cause_base = c['invoice'] && c['invoice']['subscription'] ? c['invoice']['subscription'] : c
- category_id = cause_base['metadata']['discourse_cause'].to_i
-
- backer_base = c['customer']
- backer_user_id = backer_base['metadata']['discourse_user_id'].to_i
- backer_email = backer_base['email']
-
- if category_id > 0 && Category.exists?(id: category_id)
- categories.push(category_id)
-
- current = totals[category_id] || {}
- amount = c['amount'].to_i
- date = Time.at(c['created']).to_datetime
-
- totals[category_id] ||= {}
- totals[category_id][:total] ||= 0
- totals[category_id][:month] ||= 0
-
- totals[category_id][:total] += amount
-
- if date.month == Date.today.month
- totals[category_id][:month] += amount
- end
-
- backers[category_id] ||= []
-
- if backer_user_id > 0 && User.exists?(id: backer_user_id)
- backers[category_id].push(backer_user_id) unless backers[category_id].include? backer_user_id
- elsif user = User.find_by_email(backer_email)
- backers[category_id].push(user.id) unless backers[category_id].include? user.id
- end
- end
- end
-
- categories.each do |category_id|
- category = Category.find(category_id)
-
- if totals[category_id]
- category.custom_fields['donations_total'] = totals[category_id][:total]
- category.custom_fields['donations_month'] = totals[category_id][:month]
- end
-
- if backers[category_id]
- category.custom_fields['donations_backers'] = backers[category_id]
- end
-
- category.save_custom_fields(true)
- end
- end
- end
-end
diff --git a/app/services/discourse_donations/rewards.rb b/app/services/discourse_donations/rewards.rb
deleted file mode 100644
index 93596c4..0000000
--- a/app/services/discourse_donations/rewards.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-module DiscourseDonations
- class Rewards
- attr_reader :user
-
- def initialize(user)
- @user = user
- end
-
- def add_to_group(name)
- grp = ::Group.find_by_name(name)
- return if grp.nil?
- log_group_add(grp)
- grp.add(user)
- end
-
- def grant_badge(name)
- return unless SiteSetting.enable_badges
- badge = ::Badge.find_by_name(name)
- return if badge.nil?
- BadgeGranter.grant(badge, user)
- end
-
- private
-
- def log_group_add(grp)
- system_user = User.find(-1)
- GroupActionLogger.new(system_user, grp).log_add_user_to_group(user)
- end
- end
-end
diff --git a/app/services/discourse_donations/stripe.rb b/app/services/discourse_donations/stripe.rb
deleted file mode 100644
index 199d59e..0000000
--- a/app/services/discourse_donations/stripe.rb
+++ /dev/null
@@ -1,273 +0,0 @@
-# frozen_string_literal: true
-
-module DiscourseDonations
- class Stripe
- attr_reader :charge, :currency, :description
-
- def initialize(secret_key, opts)
- ::Stripe.api_key = secret_key
- @description = opts[:description]
- @currency = opts[:currency]
- end
-
- def checkoutCharge(user = nil, email, token, amount)
- customer = customer(user,
- email: email,
- source: token,
- create: true
- )
-
- return if !customer
-
- charge = ::Stripe::Charge.create(
- customer: customer.id,
- amount: amount,
- description: @description,
- currency: @currency
- )
-
- charge
- end
-
- def charge(user = nil, opts)
- customer = customer(user,
- email: opts[:email],
- source: opts[:token],
- create: true
- )
-
- return if !customer
-
- metadata = {
- discourse_cause: opts[:cause]
- }
-
- if (user)
- metadata[:discourse_user_id] = user.id
- end
-
- @charge = ::Stripe::Charge.create(
- customer: customer.id,
- amount: opts[:amount],
- description: @description,
- currency: @currency,
- receipt_email: customer.email,
- metadata: metadata
- )
-
- @charge
- end
-
- def subscribe(user = nil, opts)
- customer = customer(user,
- email: opts[:email],
- source: opts[:token],
- create: true
- )
-
- return if !customer
-
- type = opts[:type]
- amount = opts[:amount]
-
- plans = ::Stripe::Plan.list
- plan_id = create_plan_id(type, amount)
-
- unless plans.data && plans.data.any? { |p| p['id'] === plan_id }
- result = create_plan(type, amount)
-
- plan_id = result['id']
- end
-
- ::Stripe::Subscription.create(
- customer: customer.id,
- items: [{
- plan: plan_id
- }],
- metadata: {
- discourse_cause: opts[:cause],
- discourse_user_id: user.id
- }
- )
- end
-
- def list(user, opts = {})
- customer = customer(user, opts)
-
- return if !customer
-
- result = { customer: customer }
-
- 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, status: 'all')
- raw_subscriptions = raw_subscriptions.is_a?(Object) ? raw_subscriptions['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 invoices_for_subscription(user, opts)
- customer = customer(user,
- email: opts[:email]
- )
-
- invoices = []
-
- if customer
- result = ::Stripe::Invoice.list(
- customer: customer.id,
- subscription: opts[:subscription_id]
- )
-
- invoices = result['data'] if result['data']
- end
-
- invoices
- end
-
- def cancel_subscription(subscription_id)
- if subscription = ::Stripe::Subscription.retrieve(subscription_id)
- result = subscription.delete
-
- if result['status'] === 'canceled'
- { success: true, subscription: subscription }
- else
- { success: false, message: I18n.t('donations.subscription.error.not_cancelled') }
- end
- else
- { success: false, message: I18n.t('donations.subscription.error.not_found') }
- end
- end
-
- def customer(user, opts = {})
- customer = nil
-
- if user && user.stripe_customer_id
- begin
- customer = ::Stripe::Customer.retrieve(user.stripe_customer_id)
- rescue ::Stripe::StripeError => e
- user.custom_fields['stripe_customer_id'] = nil
- user.save_custom_fields(true)
- customer = nil
- end
- end
-
- if !customer && opts[:email]
- begin
- customers = ::Stripe::Customer.list(email: opts[:email])
-
- if customers && customers['data']
- customer = customers['data'].first if customers['data'].any?
- end
-
- if customer && user
- user.custom_fields['stripe_customer_id'] = customer.id
- user.save_custom_fields(true)
- end
- rescue ::Stripe::StripeError => e
- customer = nil
- end
- end
-
- if !customer && opts[:create]
- customer_opts = {
- email: opts[:email],
- source: opts[:source]
- }
-
- if user
- customer_opts[:metadata] = {
- discourse_user_id: user.id
- }
- end
-
- customer = ::Stripe::Customer.create(customer_opts)
-
- if user
- user.custom_fields['stripe_customer_id'] = customer.id
- user.save_custom_fields(true)
- end
- end
-
- customer
- end
-
- def successful?
- @charge[:paid]
- end
-
- def create_plan(type, amount)
- id = create_plan_id(type, amount)
- nickname = id.gsub(/_/, ' ').titleize
-
- products = ::Stripe::Product.list(type: 'service')
-
- if products['data'] && products['data'].any? { |p| p['id'] === product_id }
- product = product_id
- else
- result = create_product
- product = result['id']
- end
-
- ::Stripe::Plan.create(
- id: id,
- nickname: nickname,
- interval: type,
- currency: @currency,
- product: product,
- amount: amount.to_i
- )
- end
-
- def create_product
- ::Stripe::Product.create(
- id: product_id,
- name: product_name,
- type: 'service'
- )
- end
-
- def product_id
- @product_id ||= "#{SiteSetting.title}_recurring_donation".freeze
- end
-
- def product_name
- @product_name ||= I18n.t('donations.recurring', site_title: SiteSetting.title)
- end
-
- def create_plan_id(type, amount)
- "discourse_donation_recurring_#{type}_#{amount}".freeze
- end
- end
-end
diff --git a/app/services/services.rb b/app/services/services.rb
deleted file mode 100644
index 73924a0..0000000
--- a/app/services/services.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# frozen_string_literal: true
-
-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-form.es6 b/assets/javascripts/discourse/components/donation-form.es6
deleted file mode 100644
index 84e446d..0000000
--- a/assets/javascripts/discourse/components/donation-form.es6
+++ /dev/null
@@ -1 +0,0 @@
-export default Ember.Component.extend({});
diff --git a/assets/javascripts/discourse/components/donation-list.js.es6 b/assets/javascripts/discourse/components/donation-list.js.es6
deleted file mode 100644
index b9fcea7..0000000
--- a/assets/javascripts/discourse/components/donation-list.js.es6
+++ /dev/null
@@ -1,5 +0,0 @@
-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/donation-row.js.es6 b/assets/javascripts/discourse/components/donation-row.js.es6
deleted file mode 100644
index fb2ab1a..0000000
--- a/assets/javascripts/discourse/components/donation-row.js.es6
+++ /dev/null
@@ -1,99 +0,0 @@
-import { ajax } from "discourse/lib/ajax";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-import { formatAnchor, formatAmount } from "../lib/donation-utilities";
-import { default as computed } from "ember-addons/ember-computed-decorators";
-import showModal from "discourse/lib/show-modal";
-
-export default Ember.Component.extend({
- classNameBindings: [":donation-row", "canceled", "updating"],
- includePrefix: Ember.computed.or("invoice", "charge"),
- canceled: Ember.computed.equal("subscription.status", "canceled"),
-
- @computed("subscription", "invoice", "charge", "customer")
- data(subscription, invoice, charge, customer) {
- if (subscription) {
- return $.extend({}, subscription.plan, {
- anchor: subscription.billing_cycle_anchor
- });
- } else if (invoice) {
- let receiptSent = false;
-
- if (invoice.receipt_number && customer.email) {
- receiptSent = true;
- }
-
- return $.extend({}, invoice.lines.data[0], {
- anchor: invoice.date,
- invoiceLink: invoice.invoice_pdf,
- receiptSent
- });
- } else if (charge) {
- let receiptSent = false;
-
- if (charge.receipt_number && charge.receipt_email) {
- receiptSent = true;
- }
-
- return $.extend({}, charge, {
- anchor: charge.created,
- receiptSent
- });
- }
- },
-
- @computed("data.currency")
- currency(currency) {
- return currency ? currency.toUpperCase() : null;
- },
-
- @computed("data.amount", "currency")
- amount(amount, currency) {
- return formatAmount(amount, currency);
- },
-
- @computed("data.interval")
- interval(interval) {
- return interval || "once";
- },
-
- @computed("data.anchor", "interval")
- period(anchor, interval) {
- return I18n.t(`discourse_donations.period.${interval}`, {
- anchor: formatAnchor(interval, moment.unix(anchor))
- });
- },
-
- cancelSubscription() {
- const subscriptionId = this.get("subscription.id");
- this.set("updating", true);
-
- ajax("/donate/charges/cancel-subscription", {
- data: {
- subscription_id: subscriptionId
- },
- method: "put"
- })
- .then(result => {
- if (result.success) {
- this.set("subscription", result.subscription);
- }
- })
- .catch(popupAjaxError)
- .finally(() => {
- this.set("updating", false);
- });
- },
-
- actions: {
- cancelSubscription() {
- showModal("cancel-subscription", {
- model: {
- currency: this.get("currency"),
- amount: this.get("amount"),
- period: this.get("period"),
- confirm: () => this.cancelSubscription()
- }
- });
- }
- }
-});
diff --git a/assets/javascripts/discourse/components/stripe-card.js.es6 b/assets/javascripts/discourse/components/stripe-card.js.es6
deleted file mode 100644
index 3af07c6..0000000
--- a/assets/javascripts/discourse/components/stripe-card.js.es6
+++ /dev/null
@@ -1,286 +0,0 @@
-import { ajax } from "discourse/lib/ajax";
-import { formatAnchor, zeroDecimalCurrencies } from "../lib/donation-utilities";
-import { default as computed } from "ember-addons/ember-computed-decorators";
-import { emailValid as emailValidHelper } from "discourse/lib/utilities";
-
-export default Ember.Component.extend({
- result: [],
- stripe: null,
- transactionInProgress: null,
- settings: null,
- showTransactionFeeDescription: false,
- includeTransactionFee: true,
-
- init() {
- this._super(...arguments);
-
- const user = this.get("currentUser");
- const settings = Discourse.SiteSettings;
-
- this.setProperties({
- create_accounts:
- !user && settings.discourse_donations_enable_create_accounts,
- stripe: Stripe(settings.discourse_donations_public_key),
- color: jQuery("body").css("color")
- });
-
- const types = settings.discourse_donations_types.split("|") || [];
- const amounts = this.get("donateAmounts");
-
- this.setProperties({
- types,
- type: types[0],
- amount: amounts[0].value
- });
- },
-
- @computed
- causes() {
- const categoryEnabled =
- Discourse.SiteSettings.discourse_donations_cause_category;
-
- if (categoryEnabled) {
- let categoryIds = Discourse.SiteSettings.discourse_donations_causes_categories.split(
- "|"
- );
-
- if (categoryIds.length) {
- categoryIds = categoryIds.map(Number);
- return this.site
- .get("categoriesList")
- .filter(c => {
- return categoryIds.indexOf(c.id) > -1;
- })
- .map(c => {
- return {
- id: c.id,
- name: c.name
- };
- });
- } else {
- return [];
- }
- } else {
- const causes = Discourse.SiteSettings.discourse_donations_causes;
- return causes ? causes.split("|") : [];
- }
- },
-
- @computed("types")
- donationTypes(types) {
- return types.map(type => {
- return {
- id: type,
- name: I18n.t(`discourse_donations.types.${type}`)
- };
- });
- },
-
- @computed("type")
- period(type) {
- return I18n.t(`discourse_donations.period.${type}`, {
- anchor: formatAnchor(type)
- });
- },
-
- @computed
- donateAmounts() {
- const setting = Discourse.SiteSettings.discourse_donations_amounts.split(
- "|"
- );
- if (setting.length) {
- return setting.map(amount => {
- return {
- value: parseInt(amount, 10),
- name: `${amount}.00`
- };
- });
- } else {
- return [];
- }
- },
-
- @computed("stripe")
- card(stripe) {
- const color = this.get("color");
- const hidePostalCode = !Discourse.SiteSettings.discourse_donations_zip_code;
- const elements = stripe.elements();
-
- const style = {
- base: {
- color,
- iconColor: color,
- "::placeholder": { color }
- }
- };
-
- const card = elements.create("card", { style, hidePostalCode });
-
- 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")
- transactionFee(amount) {
- const fixed =
- Discourse.SiteSettings.discourse_donations_transaction_fee_fixed;
- const percent =
- Discourse.SiteSettings.discourse_donations_transaction_fee_percent;
- const fee = (amount + fixed) / (1 - percent) - amount;
- return Math.round(fee * 100) / 100;
- },
-
- @computed("amount", "transactionFee", "includeTransactionFee")
- totalAmount(amount, fee, include) {
- if (include) return amount + fee;
- return amount;
- },
-
- @computed("email")
- emailValid(email) {
- return emailValidHelper(email);
- },
-
- @computed("email", "emailValid")
- showEmailError(email, emailValid) {
- return email && email.length > 3 && !emailValid;
- },
-
- @computed("currentUser", "emailValid")
- userReady(currentUser, emailValid) {
- return currentUser || emailValid;
- },
-
- @computed("cause")
- causeValid(cause) {
- return cause || !Discourse.SiteSettings.discourse_donations_cause_required;
- },
-
- @computed("userReady", "stripeReady", "causeValid")
- formIncomplete(userReady, stripeReady, causeValid) {
- return !userReady || !stripeReady || !causeValid;
- },
-
- @computed("transactionInProgress", "formIncomplete")
- disableSubmit(transactionInProgress, formIncomplete) {
- return transactionInProgress || formIncomplete;
- },
-
- didInsertElement() {
- this._super();
- this.get("card").mount("#card-element");
- jQuery(document).on("click", Ember.run.bind(this, this.documentClick));
- },
-
- willDestroyElement() {
- jQuery(document).off("click", Ember.run.bind(this, this.documentClick));
- },
-
- documentClick(e) {
- let $element = jQuery(".transaction-fee-description");
- let $target = jQuery(e.target);
- if ($target.closest($element).length < 1 && this._state !== "destroying") {
- this.set("showTransactionFeeDescription", false);
- }
- },
-
- setSuccess() {
- this.set("paymentSuccess", true);
- },
-
- endTranscation() {
- this.set("transactionInProgress", false);
- },
-
- concatMessages(messages) {
- this.set("result", this.get("result").concat(messages));
- },
-
- actions: {
- toggleTransactionFeeDescription() {
- this.toggleProperty("showTransactionFeeDescription");
- },
-
- submitStripeCard() {
- let self = this;
- this.set("transactionInProgress", true);
-
- this.get("stripe")
- .createToken(this.get("card"))
- .then(data => {
- self.set("result", []);
-
- if (data.error) {
- this.setProperties({
- stripeError: data.error.message,
- stripeReady: false
- });
- self.endTranscation();
- } else {
- const settings = Discourse.SiteSettings;
-
- const transactionFeeEnabled =
- settings.discourse_donations_enable_transaction_fee;
- let amount = transactionFeeEnabled
- ? this.get("totalAmount")
- : this.get("amount");
-
- if (
- zeroDecimalCurrencies.indexOf(
- settings.discourse_donations_currency
- ) === -1
- ) {
- amount = amount * 100;
- }
-
- let params = {
- stripeToken: data.token.id,
- cause: self.get("cause"),
- type: self.get("type"),
- amount,
- email: self.get("email"),
- username: self.get("username"),
- create_account: self.get("create_accounts")
- };
-
- if (!self.get("paymentSuccess")) {
- ajax("/donate/charges", {
- data: params,
- method: "post"
- }).then(result => {
- if (result.subscription) {
- let subscription = $.extend({}, result.subscription, {
- new: true
- });
- this.get("subscriptions").unshiftObject(subscription);
- }
-
- if (result.charge) {
- let charge = $.extend({}, result.charge, {
- new: true
- });
- this.get("charges").unshiftObject(charge);
- }
-
- self.concatMessages(result.messages);
-
- self.endTranscation();
- self.onCompleteTransation();
- });
- }
- }
- });
- }
- }
-});
diff --git a/assets/javascripts/discourse/connectors/below-site-header/donations-category-header-container.hbs b/assets/javascripts/discourse/connectors/below-site-header/donations-category-header-container.hbs
deleted file mode 100644
index 6e2c7bb..0000000
--- a/assets/javascripts/discourse/connectors/below-site-header/donations-category-header-container.hbs
+++ /dev/null
@@ -1,3 +0,0 @@
-{{#if siteSettings.discourse_donations_cause_category}}
- {{mount-widget widget="category-header-widget" args=(hash currentPath=currentPath)}}
-{{/if}}
diff --git a/assets/javascripts/discourse/connectors/category-custom-settings/donations_category_settings.hbs b/assets/javascripts/discourse/connectors/category-custom-settings/donations_category_settings.hbs
deleted file mode 100644
index c448fec..0000000
--- a/assets/javascripts/discourse/connectors/category-custom-settings/donations_category_settings.hbs
+++ /dev/null
@@ -1,36 +0,0 @@
-{{#if siteSettings.discourse_donations_cause_category}}
-
- {{input type="checkbox" checked=category.custom_fields.donations_show_amounts}}
- {{i18n 'discourse_donations.cause.amounts.setting_label'}}
-
-
-
-
- {{text-field value=category.custom_fields.donations_github placeholderKey="discourse_donations.cause.github.setting_placeholder"}}
-
-
-
-
- {{text-field value=category.custom_fields.donations_meta placeholderKey="discourse_donations.cause.meta.setting_placeholder"}}
-
-
-
-
- {{user-selector usernames=category.custom_fields.donations_maintainers}}
-
-
-
-
- {{input value=category.custom_fields.donations_maintainers_label}}
-
-
-
-
- {{input value=category.custom_fields.donations_release_latest}}
-
-
-
-
- {{input value=category.custom_fields.donations_release_oldest}}
-
-{{/if}}
diff --git a/assets/javascripts/discourse/connectors/extra-nav-item/donate.hbs b/assets/javascripts/discourse/connectors/extra-nav-item/donate.hbs
deleted file mode 100644
index 69bb4ec..0000000
--- a/assets/javascripts/discourse/connectors/extra-nav-item/donate.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-{{#if siteSettings.discourse_donations_enabled}}
-
- {{i18n 'discourse_donations.nav_item'}}
-
-{{/if}}
diff --git a/assets/javascripts/discourse/controllers/cancel-subscription.js.es6 b/assets/javascripts/discourse/controllers/cancel-subscription.js.es6
deleted file mode 100644
index c6949b0..0000000
--- a/assets/javascripts/discourse/controllers/cancel-subscription.js.es6
+++ /dev/null
@@ -1,12 +0,0 @@
-export default Ember.Controller.extend({
- actions: {
- confirm() {
- this.get("model.confirm")();
- this.send("closeModal");
- },
-
- cancel() {
- this.send("closeModal");
- }
- }
-});
diff --git a/assets/javascripts/discourse/controllers/donate.js.es6 b/assets/javascripts/discourse/controllers/donate.js.es6
deleted file mode 100644
index 8cba1ae..0000000
--- a/assets/javascripts/discourse/controllers/donate.js.es6
+++ /dev/null
@@ -1,61 +0,0 @@
-import { default as computed } from "ember-addons/ember-computed-decorators";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-import { ajax } from "discourse/lib/ajax";
-import { getOwner } from "discourse-common/lib/get-owner";
-import { emailValid } from "discourse/lib/utilities";
-
-export default Ember.Controller.extend({
- loadingDonations: false,
- loadDonationsDisabled: Ember.computed.not("emailVaild"),
-
- @computed("charges.[]", "subscriptions.[]")
- hasDonations(charges, subscriptions) {
- return (
- (charges && charges.length > 0) ||
- (subscriptions && subscriptions.length > 0)
- );
- },
-
- @computed("email")
- emailVaild(email) {
- return emailValid(email);
- },
-
- actions: {
- stripeTransationCompleteCtr() {},
-
- loadDonations() {
- let email = this.get("email");
-
- this.set("loadingDonations", true);
-
- ajax("/donate/charges", {
- data: { email },
- type: "GET"
- })
- .then(result => {
- this.setProperties({
- charges: Ember.A(result.charges),
- subscriptions: Ember.A(result.subscriptions),
- customer: result.customer
- });
- })
- .catch(popupAjaxError)
- .finally(() => {
- this.setProperties({
- loadingDonations: false,
- hasEmailResult: true
- });
-
- Ember.run.later(() => {
- this.set("hasEmailResult", false);
- }, 6000);
- });
- },
-
- showLogin() {
- const controller = getOwner(this).lookup("route:application");
- controller.send("showLogin");
- }
- }
-});
diff --git a/assets/javascripts/discourse/discourse-patrons-map.js b/assets/javascripts/discourse/discourse-patrons-map.js
new file mode 100644
index 0000000..26de642
--- /dev/null
+++ b/assets/javascripts/discourse/discourse-patrons-map.js
@@ -0,0 +1,12 @@
+
+export default function() {
+ const { disabled_plugins = [] } = this.site;
+
+ if (disabled_plugins.indexOf("discourse-patrons") !== -1) {
+ return;
+ }
+
+ this.route("patrons", function() {
+ this.route("show", { path: ":payment_id" });
+ });
+}
diff --git a/assets/javascripts/discourse/discourse-payments-route-map.js.es6 b/assets/javascripts/discourse/discourse-payments-route-map.js.es6
deleted file mode 100644
index dbf4000..0000000
--- a/assets/javascripts/discourse/discourse-payments-route-map.js.es6
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function() {
- this.route("donate");
-}
diff --git a/assets/javascripts/discourse/initializers/donations-edits.js.es6 b/assets/javascripts/discourse/initializers/donations-edits.js.es6
deleted file mode 100644
index 9741855..0000000
--- a/assets/javascripts/discourse/initializers/donations-edits.js.es6
+++ /dev/null
@@ -1,56 +0,0 @@
-import { withPluginApi } from "discourse/lib/plugin-api";
-
-export default {
- name: "donations-edits",
- initialize(container) {
- const siteSettings = container.lookup("site-settings:main");
-
- withPluginApi("0.8.12", api => {
- api.decorateCooked(
- $post => {
- const $form = $post.find(".stripe-checkout");
- if ($form.length) {
- const $input = $form.find("input");
- var s = document.createElement("script");
- s.src = "https://checkout.stripe.com/checkout.js";
- s.setAttribute("class", "stripe-button");
- s.setAttribute(
- "data-key",
- siteSettings.discourse_donations_public_key
- );
- s.setAttribute("data-amount", $input.attr("amount"));
- s.setAttribute(
- "data-name",
- siteSettings.discourse_donations_shop_name
- );
- s.setAttribute("data-description", $form.attr("content"));
- s.setAttribute("data-image", $form.attr("image") || "");
- s.setAttribute("data-locale", "auto");
- s.setAttribute(
- "data-zip-code",
- siteSettings.discourse_donations_zip_code
- );
- s.setAttribute(
- "data-billing-address",
- siteSettings.discourse_donations_billing_address
- );
- s.setAttribute(
- "data-currency",
- siteSettings.discourse_donations_currency
- );
- $form.append(s);
- }
- },
- { id: "discourse-donations" }
- );
-
- if (siteSettings.discourse_donations_cause_category) {
- api.decorateWidget("category-header-widget:after", helper => {
- helper.widget.appEvents.on("page:changed", () => {
- helper.widget.scheduleRerender();
- });
- });
- }
- });
- }
-};
diff --git a/assets/javascripts/discourse/lib/donation-utilities.js.es6 b/assets/javascripts/discourse/lib/donation-utilities.js.es6
deleted file mode 100644
index 619fde4..0000000
--- a/assets/javascripts/discourse/lib/donation-utilities.js.es6
+++ /dev/null
@@ -1,48 +0,0 @@
-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
deleted file mode 100644
index d9ed51a..0000000
--- a/assets/javascripts/discourse/routes/donate.js.es6
+++ /dev/null
@@ -1,40 +0,0 @@
-import DiscourseRoute from "discourse/routes/discourse";
-import DiscourseURL from "discourse/lib/url";
-import { popupAjaxError } from "discourse/lib/ajax-error";
-import { ajax } from "discourse/lib/ajax";
-
-export default DiscourseRoute.extend({
- redirect() {
- if (!Discourse.SiteSettings.discourse_donations_enabled) {
- DiscourseURL.routeTo("/");
- return;
- }
- },
-
- setupController(controller) {
- let charges = [];
- let subscriptions = [];
- let customer = {};
-
- controller.set("loadingDonations", true);
-
- ajax("/donate/charges")
- .then(result => {
- if (result) {
- charges = result.charges;
- subscriptions = result.subscriptions;
- customer = result.customer;
- }
-
- controller.setProperties({
- charges: Ember.A(charges),
- subscriptions: Ember.A(subscriptions),
- customer
- });
- })
- .catch(popupAjaxError)
- .finally(() => {
- controller.set("loadingDonations", false);
- });
- }
-});
diff --git a/assets/javascripts/discourse/templates/components/donation-form.hbs b/assets/javascripts/discourse/templates/components/donation-form.hbs
deleted file mode 100644
index 2449ad2..0000000
--- a/assets/javascripts/discourse/templates/components/donation-form.hbs
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/assets/javascripts/discourse/templates/components/donation-list.hbs b/assets/javascripts/discourse/templates/components/donation-list.hbs
deleted file mode 100644
index 4a23964..0000000
--- a/assets/javascripts/discourse/templates/components/donation-list.hbs
+++ /dev/null
@@ -1,28 +0,0 @@
-{{#if hasSubscriptions}}
-
-
{{i18n 'discourse_donations.donations.subscriptions'}}
-
- {{#each subscriptions as |s|}}
- - {{donation-row subscription=s.subscription customer=customer new=s.new}}
- {{#if s.invoices}}
-
- {{#each s.invoices as |invoice|}}
- - {{donation-row invoice=invoice customer=customer new=s.new}}
- {{/each}}
-
- {{/if}}
- {{/each}}
-
-
-{{/if}}
-
-{{#if hasCharges}}
-
-
{{i18n 'discourse_donations.donations.charges'}}
-
- {{#each charges as |charge|}}
- - {{donation-row charge=charge customer=customer new=charge.new}}
- {{/each}}
-
-
-{{/if}}
diff --git a/assets/javascripts/discourse/templates/components/donation-row.hbs b/assets/javascripts/discourse/templates/components/donation-row.hbs
deleted file mode 100644
index 0e6d17a..0000000
--- a/assets/javascripts/discourse/templates/components/donation-row.hbs
+++ /dev/null
@@ -1,41 +0,0 @@
-{{#if includePrefix}}
- {{i18n 'discourse_donations.invoice_prefix'}}
-{{/if}}
-
-{{currency}}
-
-{{amount}}
-
-{{period}}
-
-{{#if invoice}}
- ({{i18n 'discourse_donations.invoice'}})
-{{/if}}
-
-{{#if currentUser}}
- {{#if subscription}}
-
- {{#if updating}}
- {{loading-spinner size='small'}}
- {{else}}
- {{#unless canceled}}
-
- {{i18n 'cancel'}}
-
- {{/unless}}
- {{/if}}
-
- {{/if}}
-{{/if}}
-
-{{#if receiptSent}}
- –
- {{i18n 'discourse_donations.receipt' email=customer.email}}
-{{/if}}
-
-{{#if new}}
-
- {{d-icon 'circle'}}
- {{i18n 'new_item'}}
-
-{{/if}}
diff --git a/assets/javascripts/discourse/templates/components/stripe-card.hbs b/assets/javascripts/discourse/templates/components/stripe-card.hbs
deleted file mode 100644
index a682436..0000000
--- a/assets/javascripts/discourse/templates/components/stripe-card.hbs
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-
- {{combo-box content=donationTypes value=type}}
-
-
-
-
-
-
- {{combo-box valueAttribute="value" content=donateAmounts value=amount}}
-
-
-
-{{#if siteSettings.discourse_donations_enable_transaction_fee}}
-
-
- {{input type="checkbox" checked=includeTransactionFee}}
-
{{i18n 'discourse_donations.transaction_fee.label' transactionFee=transactionFee currency=siteSettings.discourse_donations_currency}}
-
- {{d-icon 'info-circle'}}
- {{#if showTransactionFeeDescription}}
-
- {{i18n 'discourse_donations.transaction_fee.description'}}
-
- {{/if}}
-
-
-
-
-
-
-
- {{siteSettings.discourse_donations_currency}}
- {{totalAmount}}
- {{period}}
-
-
-{{/if}}
-
-
-
-
-
- {{#if stripeError}}
-
{{stripeError}}
- {{/if}}
-
-
-
-{{#unless currentUser}}
-
-
-
- {{text-field value=email}}
- {{#if showEmailError}}
-
{{i18n 'user.email.invalid'}}
- {{else}}
-
{{i18n 'discourse_donations.email_instructions'}}
- {{/if}}
-
-
-
- {{#if create_accounts}}
-
-
-
- {{text-field value=username}}
-
-
-
-
-
-
- {{text-field value=name}}
-
-
-
-
-
-
- {{input type="password" value=password}}
-
-
- {{/if}}
-{{/unless}}
-
-
diff --git a/assets/javascripts/discourse/templates/donate.hbs b/assets/javascripts/discourse/templates/donate.hbs
deleted file mode 100644
index 14df9a4..0000000
--- a/assets/javascripts/discourse/templates/donate.hbs
+++ /dev/null
@@ -1,40 +0,0 @@
-{{i18n 'discourse_donations.title' site_name=siteSettings.title}}
-
-
- {{cook-text siteSettings.discourse_donations_page_description}}
-
-
-
- {{donation-form
- charges=charges
- subscriptions=subscriptions
- onCompleteTransation=(action "stripeTransationCompleteCtr")
- }}
-
-
-
-
{{i18n 'discourse_donations.donations.title'}}
- {{#if loadingDonations}}
- {{i18n 'discourse_donations.donations.loading'}}
- {{loading-spinner size='small'}}
- {{else}}
- {{#if currentUser}}
- {{#if hasDonations}}
- {{donation-list charges=charges subscriptions=subscriptions customer=customer}}
- {{else}}
- {{i18n 'discourse_donations.donations.none'}}
- {{/if}}
- {{else}}
- {{#if hasDonations}}
- {{donation-list charges=charges subscriptions=subscriptions customer=customer}}
- {{else}}
- {{#if hasEmailResult}}
- {{i18n 'discourse_donations.donations.none_email' email=email}}
- {{else}}
- {{input value=email placeholder=(i18n 'email')}}
- {{d-button action='loadDonations' label='discourse_donations.donations.load' disabled=loadDonationsDisabled}}
- {{/if}}
- {{/if}}
- {{/if}}
- {{/if}}
-
diff --git a/assets/javascripts/discourse/templates/modal/cancel-subscription.hbs b/assets/javascripts/discourse/templates/modal/cancel-subscription.hbs
deleted file mode 100644
index b67cb78..0000000
--- a/assets/javascripts/discourse/templates/modal/cancel-subscription.hbs
+++ /dev/null
@@ -1,11 +0,0 @@
-{{#d-modal-body title='discourse_donations.subscription.cancel.title'}}
- {{i18n 'discourse_donations.subscription.cancel.description' site=siteSettings.title
- currency=model.currency
- amount=model.amount
- period=model.period}}
-{{/d-modal-body}}
-
-
diff --git a/assets/javascripts/discourse/templates/patrons/index.hbs b/assets/javascripts/discourse/templates/patrons/index.hbs
new file mode 100644
index 0000000..5eea065
--- /dev/null
+++ b/assets/javascripts/discourse/templates/patrons/index.hbs
@@ -0,0 +1,2 @@
+
+index
diff --git a/assets/javascripts/discourse/templates/patrons/show.hbs b/assets/javascripts/discourse/templates/patrons/show.hbs
new file mode 100644
index 0000000..a133b77
--- /dev/null
+++ b/assets/javascripts/discourse/templates/patrons/show.hbs
@@ -0,0 +1,3 @@
+
+
+show
diff --git a/assets/javascripts/discourse/widgets/donations-category-header-widget.js.es6 b/assets/javascripts/discourse/widgets/donations-category-header-widget.js.es6
deleted file mode 100644
index 9f345cb..0000000
--- a/assets/javascripts/discourse/widgets/donations-category-header-widget.js.es6
+++ /dev/null
@@ -1,196 +0,0 @@
-import { createWidget } from "discourse/widgets/widget";
-import { h } from "virtual-dom";
-import { avatarFor } from "discourse/widgets/post";
-import { userPath } from "discourse/lib/url";
-
-function donationDisplay(amount, type) {
- return h(`div.donations-${type}`, [
- h("span", I18n.t(`discourse_donations.cause.category.${type}`)),
- h("span", `$${(amount / 100).toFixed(2)}`)
- ]);
-}
-
-createWidget("category-header-widget", {
- tagName: "span",
-
- html(args) {
- const controller = this.register.lookup("controller:navigation/category");
- const category = controller.get("category");
-
- if (
- args.currentPath.toLowerCase().indexOf("category") > -1 &&
- category &&
- category.donations_cause
- ) {
- $("body").addClass("donations-category");
-
- let contents = [
- h("div.donations-category-contents", [
- h("h1", category.name),
- h("div.category-title-description", h("p", category.description_text))
- ])
- ];
-
- let metadata = [];
-
- if (category.donations_total !== undefined) {
- metadata.push(donationDisplay(category.donations_total || 0, "total"));
-
- if (Discourse.SiteSettings.discourse_donations_cause_month) {
- metadata.push(
- donationDisplay(category.donations_month || 0, "month")
- );
- }
- }
-
- if (category.donations_github) {
- metadata.push(
- h(
- "div.donations-github",
- this.attach("link", {
- icon: "github",
- label: "discourse_donations.cause.github.label",
- href: category.donations_github
- })
- )
- );
- }
-
- if (category.donations_meta) {
- metadata.push(
- h(
- "div.donations-meta",
- this.attach("link", {
- href: category.donations_meta,
- contents: () => {
- return [
- h("img.meta-icon", {
- attributes: {
- src:
- "https://discourse-meta.s3.dualstack.us-west-1.amazonaws.com/original/3X/b/1/b19ba793155a785bbd9707bc0cabbd3a987fa126.png?v=6"
- }
- }),
- h("span", I18n.t("discourse_donations.cause.meta.label"))
- ];
- }
- })
- )
- );
- }
-
- if (category.donations_release_oldest) {
- let releaseArray = category.donations_release_oldest.split("/");
- let label = releaseArray[releaseArray.length - 1];
- metadata.push(
- h("div.donations-release-oldest", [
- h("span", ">="),
- this.attach("link", {
- href: category.donations_release_oldest,
- icon: "tag",
- rawLabel: label,
- omitSpan: true,
- attributes: {
- target: "_blank"
- }
- })
- ])
- );
- }
-
- if (category.donations_release_latest) {
- let releaseArray = category.donations_release_latest.split("/");
- let label = releaseArray[releaseArray.length - 1];
- metadata.push(
- h("div.donations-release-latest", [
- h("span", "<="),
- this.attach("link", {
- href: category.donations_release_latest,
- icon: "tag",
- rawLabel: label,
- omitSpan: true,
- attributes: {
- target: "_blank"
- }
- })
- ])
- );
- }
-
- if (metadata.length) {
- contents.push(h("div.donations-category-metadata", metadata));
- }
-
- let users = [];
-
- if (category.donations_backers.length) {
- users.push(
- h("div.donations-backers", [
- h(
- "div.donations-backers-title",
- I18n.t("discourse_donations.cause.backers.label")
- ),
- category.donations_backers.map(user => {
- if (user) {
- return avatarFor("medium", {
- template: user.avatar_template,
- username: user.username,
- name: user.name,
- url: userPath(user.username),
- className: "backer-avatar"
- });
- } else {
- return;
- }
- })
- ])
- );
- }
-
- if (category.donations_maintainers.length) {
- let maintainersLabel =
- category.donations_maintainers_label ||
- I18n.t("discourse_donations.cause.maintainers.label");
-
- users.push(
- h("div.donations-maintainers", [
- h("div.donations-maintainers-title", maintainersLabel),
- category.donations_maintainers.map(user => {
- if (user) {
- return avatarFor("medium", {
- template: user.avatar_template,
- username: user.username,
- name: user.name,
- url: userPath(user.username),
- className: "maintainer-avatar"
- });
- } else {
- return;
- }
- })
- ])
- );
- }
-
- if (users.length) {
- contents.push(h("div.donations-category-users", users));
- }
-
- return h(
- "div.donations-category-header",
- {
- attributes: {
- style:
- "background-color: #" +
- category.color +
- "; color: #" +
- category.text_color +
- ";"
- }
- },
- contents
- );
- } else {
- $("body").removeClass("donations-category");
- }
- }
-});
diff --git a/assets/javascripts/lib/discourse-markdown/stripe.js.es6 b/assets/javascripts/lib/discourse-markdown/stripe.js.es6
deleted file mode 100644
index 3ce2bee..0000000
--- a/assets/javascripts/lib/discourse-markdown/stripe.js.es6
+++ /dev/null
@@ -1,104 +0,0 @@
-function validationErrors(tagInfo, content, siteSettings) {
- let errors = [];
- if (!siteSettings.discourse_donations_public_key) {
- errors.push("missing key (site setting)");
- }
- if (!siteSettings.discourse_donations_currency) {
- errors.push("missing currency (site setting)");
- }
- if (!siteSettings.discourse_donations_shop_name) {
- errors.push("missing name (site setting)");
- }
- if (!siteSettings.discourse_donations_zip_code) {
- errors.push("missing zip code toggle (site setting)");
- }
- if (!siteSettings.discourse_donations_billing_address) {
- errors.push("missing billing address toggle (site setting)");
- }
- if (!tagInfo.attrs["amount"]) {
- errors.push("missing amount");
- }
- if (!content) {
- errors.push("missing description");
- }
- return errors;
-}
-
-function replaceWithStripeOrError(siteSettings) {
- return function(state, tagInfo, content) {
- let errors = validationErrors(tagInfo, content, siteSettings);
- if (errors.length) {
- displayErrors(state, errors);
- } else {
- insertCheckout(state, tagInfo, content);
- }
- return true;
- };
-}
-
-function displayErrors(state, errors) {
- let token = state.push("div-open", "div", 1);
- token.attrs = [["class", "stripe-errors"]];
- token = state.push("html_inline", "", 0);
- token.content = "Stripe checkout can't be rendered: " + errors.join(", ");
- state.push("div-close", "div", -1);
-}
-
-function insertCheckout(state, tagInfo, content) {
- let token = state.push("stripe-checkout-form-open", "form", 1);
- token.attrs = [
- ["method", "POST"],
- ["action", "/checkout"],
- ["content", content],
- ["image", tagInfo.attrs["image"]],
- ["class", "stripe-checkout"]
- ];
-
- token = state.push("stripe-checkout-form-amount", "input", 0);
- token.attrs = [
- ["type", "hidden"],
- ["name", "amount"],
- ["value", tagInfo.attrs["amount"]]
- ];
-
- state.push("stripe-checkout-form-close", "form", -1);
-}
-
-function setupMarkdownIt(helper, siteSettings) {
- helper.registerPlugin(md => {
- md.inline.bbcode.ruler.push("stripe-checkout", {
- tag: "stripe",
- replace: replaceWithStripeOrError(siteSettings)
- });
- });
-}
-
-export function setup(helper) {
- helper.registerOptions((opts, siteSettings) => {
- helper.whiteList([
- "div[class]",
- "form[method]",
- "form[action]",
- "form[class]",
- "form[content]",
- "form[image]",
- "input[type]",
- "input[name]",
- "input[value]",
- "script[class]",
- "script[src]",
- "script[data-key]",
- "script[data-amount]",
- "script[data-name]",
- "script[data-description]",
- "script[data-image]",
- "script[data-zip-code]",
- "script[data-billing-address]",
- "script[data-currency]",
- "script[data-locale]"
- ]);
- if (helper.markdownIt) {
- setupMarkdownIt(helper, siteSettings);
- }
- });
-}
diff --git a/assets/stylesheets/common/discourse-donations.scss b/assets/stylesheets/common/discourse-donations.scss
deleted file mode 100644
index 4b2264b..0000000
--- a/assets/stylesheets/common/discourse-donations.scss
+++ /dev/null
@@ -1,218 +0,0 @@
-div.stripe-errors {
- border: 1px solid #c33;
- border-radius: 5px;
- color: #600;
- background-color: #fdd;
- padding: 5px 10px;
-}
-
-.donations-page-description {
- max-width: 700px;
- font-size: 1.1em;
- line-height: 24px;
-}
-
-.donations-page-payment {
- padding: 30px 0;
-
- #payment-form {
- .control-label {
- margin: 0 6.5px;
- }
-
- .select-kit ul {
- margin: 0;
- }
-
- input[type="checkbox"] {
- margin: 0;
- }
-
- .error,
- .stripe-error {
- margin-top: 5px;
- color: $danger;
- }
- }
-}
-
-.transaction-fee-description {
- position: relative;
- display: inline-block;
- margin-left: 5px;
- cursor: pointer;
-}
-
-.transaction-fee-description-modal {
- display: block;
- position: absolute;
- top: -30px;
- left: 20px;
- background-color: $secondary;
- border: 1px solid $primary-low;
- padding: 10px;
- box-shadow: 0 2px 2px rgba(0, 0, 0, 0.4);
- width: 400px;
- z-index: 1;
-}
-
-.body-page .donations-page-donations {
- margin-bottom: 20px;
-
- .donation-list {
- .subscription-list,
- .charge-list {
- margin-bottom: 10px;
-
- > ul {
- margin: 10px 0;
- list-style: none;
-
- .spinner {
- height: 5px;
- width: 5px;
- }
- }
- }
-
- .underline {
- border-bottom: 1px solid $primary-medium;
- display: inline-block;
- }
- }
-}
-
-.donation-row {
- span {
- line-height: 25px;
- }
-
- &.canceled {
- text-decoration: line-through;
- }
-
- &.updating {
- color: $primary-low;
- }
-
- .new-flag {
- color: $tertiary;
- margin-left: 5px;
-
- .fa {
- line-height: 16px;
- font-size: 8px;
- }
-
- > * {
- display: inline-block;
- vertical-align: middle;
- }
- }
-}
-
-.donations-category-header {
- padding-top: 60px;
- text-align: center;
-
- .donations-category-contents {
- max-width: 500px;
- margin: 0 auto;
- padding: 30px 40px 10px;
- text-align: center;
-
- i {
- margin-right: 0.25em;
- font-size: 1.5em;
- }
-
- h1 {
- text-transform: capitalize;
- display: inline;
- }
-
- .category-title-description {
- font-size: 1.2rem;
- padding: 10px 0;
-
- p {
- margin: 0;
- }
- }
- }
-
- .donations-category-metadata {
- max-width: 700px;
- margin: 0 auto;
- padding-bottom: 20px;
- display: flex;
- justify-content: space-around;
- font-size: 1.2rem;
-
- .donations-total span:first-of-type,
- .donations-month span:first-of-type {
- margin-right: 5px;
- }
-
- .donations-github a,
- .donations-meta a {
- color: inherit;
- }
-
- .donations-meta {
- .widget-link {
- display: flex;
- align-items: center;
- }
- img {
- width: 17px;
- height: 17px;
- margin-right: 4px;
- }
- }
-
- .donations-release-latest,
- .donations-release-oldest {
- display: flex;
- align-items: center;
-
- span:first-of-type {
- margin-right: 10px;
- }
-
- a {
- color: white;
- }
- }
- }
-
- .donations-category-users {
- max-width: 500px;
- margin: 0 auto;
- font-size: 1.2rem;
- padding-bottom: 30px;
- display: flex;
- align-items: center;
-
- .donations-backers,
- .donations-maintainers {
- flex: 1 1 auto;
- }
-
- .backer-avatar,
- .maintainer-avatar {
- margin: 0 5px;
- }
-
- .donations-backers-title,
- .donations-maintainers-title {
- padding-bottom: 10px;
- }
- }
-}
-
-.donations-category {
- #main-outlet {
- padding-top: 20px;
- }
-}
diff --git a/assets/stylesheets/mobile/discourse-donations.scss b/assets/stylesheets/mobile/discourse-donations.scss
deleted file mode 100644
index b99f3da..0000000
--- a/assets/stylesheets/mobile/discourse-donations.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-.donations-category-header .donations-category-metadata {
- flex-flow: wrap;
- padding: 0 10px;
-
- div {
- padding-bottom: 10px;
- }
-}
diff --git a/config/locales/client.de.yml b/config/locales/client.de.yml
deleted file mode 100644
index 92fed55..0000000
--- a/config/locales/client.de.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-en:
- js:
- discourse_donations:
- title: Spenden
- nav_item: Spenden
- amount: Betrag
- card: Kreditkarte oder Bankkarte
- submit: Spende bezahlen
- messages:
- success: Thank you for your donation!
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
deleted file mode 100644
index 2f796f3..0000000
--- a/config/locales/client.en.yml
+++ /dev/null
@@ -1,96 +0,0 @@
-en:
- site_settings:
- discourse_donations_enabled: "Enable the Discourse Donations plugin."
- discourse_donations_enable_create_accounts: "EXPERIMENTAL: Enable anonymous users to create accounts after successful payment"
- discourse_donations_secret_key: "Stripe Secret Key"
- discourse_donations_public_key: "Stripe Public Key"
- discourse_donations_shop_name: "Shop Name shown in Stripe Checkout form"
- discourse_donations_description: "Description shown in Stripe Checkout form"
- discourse_donations_currency: "Currency Code"
- discourse_donations_zip_code: "Show Zip Code"
- discourse_donations_billing_address: "Collect billing address"
- discourse_donations_reward_badge_name: "Grant this badge to user when a payment is successful"
- discourse_donations_reward_group_name: "Add the user to this group when a payment is successful"
- discourse_donations_page_description: "Text to be added to /donate page. Markdown is supported."
- discourse_donations_enable_transaction_fee: "Give the user the option of including the Stripe transaction fee in their donation."
- discourse_donations_transaction_fee_fixed: "Fixed part of Stripe transaction fee (changes per region). See Stripe's pricing for your region and Stripe's explaination of passing fees onto customers."
- discourse_donations_transaction_fee_percent: "Percent part of Stripe transaction fee (changes per region). See Stripe's pricing for your region and Stripe's explaination of passing fees onto customers."
- discourse_donations_amounts: "Donation amounts available to user. First listed will be the default."
- discourse_donations_custom_amount: "Allow custom donation amount"
- discourse_donations_types: "Donation types. First listed will be the default."
- discourse_donations_causes: "Custom causes a user can donate to."
- discourse_donations_causes_categories: "Categories of cause a user can donate do."
- discourse_donations_cause_category: "Category causes enabled."
- discourse_donations_cause_required: "Require user to select a cause when donating."
- discourse_donations_cause_month: "Show monthly total of donations to each cause."
- errors:
- discourse_donations_amount_must_be_number: "Amounts must be numbers"
-
- js:
- discourse_donations:
- nav_item: Donate
- title: "Make a Donation"
- amount: Amount
- card: Card
- submit: Donate
- submit_with_create_account: Make Payment and Create Account
- invoice: "invoice"
- invoice_prefix: "You gave"
- receipt: "Receipt sent to {{email}}."
- cause:
- label: "Cause"
- placeholder: "Select a cause"
- category:
- total: "Total"
- month: "Month"
- backers:
- label: "Backers"
- github:
- label: "Repository"
- setting_label: "Github"
- setting_placeholder: "repoistory url"
- meta:
- label: "Discussion"
- setting_label: "Meta"
- setting_placeholder: "topic url"
- maintainers:
- label: "Maintainers"
- setting_label: "Maintainers label"
- amounts:
- setting_label: "Show donation amounts"
- release_latest:
- label: "Latest Release Supported"
- release_oldest:
- label: "Oldest Release Supported"
- subscription:
- cancel:
- title: "Cancel Recurring Donation"
- description: >
- Are you sure you want to cancel your recurring donation to {{site}}
- of {{currency}} {{amount}} {{period}}?
- 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."
- total: "Total"
- messages:
- success: Thank you for your donation!
- type: "Type"
- types:
- once: "Once"
- week: "Weekly"
- month: "Monthly"
- year: "Yearly"
- period:
- once: "on {{anchor}}"
- week: "every week on {{anchor}}"
- month: "on the {{anchor}} of every month"
- year: "every year on {{anchor}}"
- donations:
- title: "Your Donations"
- load: "Load Donations"
- loading: "Loading donations"
- charges: "Once Off"
- subscriptions: "Recurring"
- none: "You haven't made a donation yet."
- none_email: "There are no donations for {{email}}."
diff --git a/config/locales/client.fi.yml b/config/locales/client.fi.yml
deleted file mode 100644
index 351f1cd..0000000
--- a/config/locales/client.fi.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-fi:
- site_settings:
- discourse_donations_enabled: Ota käyttöön lahjoituslisäosa.
- discourse_donations_secret_key: Stripen Secret Key -salausavain
- discourse_donations_public_key: Stripen Public Key -tunnistusavain
- discourse_donations_currency: Valuuttakoodi
- js:
- discourse_donations:
- title: Lahjoita
- nav_item: Lahjoita
- amount: Määrä
- card: Credit- vai debit-kortti
- submit: Maksa
- messages:
- success: Kiitos lahjoituksestasi!
diff --git a/config/locales/client.it.yml b/config/locales/client.it.yml
deleted file mode 100644
index fe95322..0000000
--- a/config/locales/client.it.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-it:
- site_settings:
- discourse_donations_enabled: Abilita il plugin per le donazioni.
- discourse_donations_enable_create_accounts: "SPERIMENTALE: Permetti agli utenti anonimi la creazione di un account dopo un pagamento effettuato con successo"
- discourse_donations_secret_key: Stripe Secret Key
- discourse_donations_public_key: Stripe Public Key
- discourse_donations_currency: Codice Valuta
- discourse_donations_reward_badge_name: Assegna questo distintivo all'utente quando un pagamento viene effettuato con successo
- discourse_donations_reward_group_name: Aggiungi l'utente a questo gruppo quando un pagamento viene effettuato con successo
- js:
- discourse_donations:
- title: Donazione
- nav_item: Donazione
- amount: Importo
- card: Carta di credito o debito
- submit: Effettua il pagamento
- submit_with_create_account: Effettua il Pagamento e Crea un Account
- messages:
- success: Grazie per la tua donazione!
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
deleted file mode 100644
index c72bc8f..0000000
--- a/config/locales/server.en.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-en:
- donations:
- recurring: "%{site_title} Recurring Donation"
- payment:
- 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}.'
- subscription:
- error:
- not_found: "Subscription not found."
- not_cancelled: "Subscription not cancelled."
diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml
deleted file mode 100644
index 059a90b..0000000
--- a/config/locales/server.it.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-it:
- donations:
- payment:
- success: 'Grazie. La tua donazione è stata effettuata con successo'
diff --git a/config/routes.rb b/config/routes.rb
index 5314102..6367814 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,10 +1,6 @@
# frozen_string_literal: true
-DiscourseDonations::Engine.routes.draw do
- get '/' => 'charges#index'
-
- resources :charges, only: [:index, :create]
- put '/charges/cancel-subscription' => 'charges#cancel_subscription'
-
- resources :checkout, only: [:create]
+DiscoursePatrons::Engine.routes.draw do
+ get '/' => 'patrons#index'
+ get '/:id' => 'patrons#show'
end
diff --git a/config/settings.yml b/config/settings.yml
index 898c70e..de4e71f 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -1,78 +1,21 @@
plugins:
- discourse_donations_enabled:
+ discourse_patrons_enabled:
default: false
client: true
- discourse_donations_secret_key:
+ discourse_patrons_secret_key:
default: ''
client: false
- discourse_donations_public_key:
+ discourse_patrons_public_key:
default: ''
client: true
- discourse_donations_enable_create_accounts:
+ discourse_patrons_currency:
client: true
- default: false
- discourse_donations_description:
- client: true
- default: ''
- discourse_donations_shop_name:
- client: true
- default: ''
- discourse_donations_currency:
- client: true
- default: 'USD'
- discourse_donations_zip_code:
- default: false
- client: true
- discourse_donations_billing_address:
- default: true
- client: true
- discourse_donations_reward_badge_name:
- client: false
- default: 'Donation'
- discourse_donations_reward_group_name:
- client: false
- default: 'Donation'
- discourse_donations_page_description:
- client: true
- default: ''
- discourse_donations_enable_transaction_fee:
- client: true
- default: false
- discourse_donations_transaction_fee_fixed:
- client: true
- default: 0.3
- discourse_donations_transaction_fee_percent:
- client: true
- default: 0.029
- discourse_donations_amounts:
- client: true
- type: list
- default: '1|2|5|10|20|50'
- regex: "^[0-9\\|]+$"
- regex_error: "site_settings.errors.discourse_donations_amount_must_be_number"
- discourse_donations_types:
- client: true
- type: list
- default: 'once|month'
+ default: "USD"
+ type: enum
choices:
- - year
- - month
- - week
- - once
- discourse_donations_causes:
- client: true
- type: list
- default: ''
- discourse_donations_causes_categories:
- client: true
- type: category_list
- default: ''
- discourse_donations_cause_category:
- client: true
- default: false
- discourse_donations_cause_required:
- client: true
- default: false
- discourse_donations_cause_month:
- client: true
- default: false
+ - AUD
+ - CAD
+ - EUR
+ - JPY
+ - GBP
+ - USD
diff --git a/doc/menulink.png b/doc/menulink.png
deleted file mode 100644
index ba820af..0000000
Binary files a/doc/menulink.png and /dev/null differ
diff --git a/doc/post-payment.png b/doc/post-payment.png
deleted file mode 100644
index 7a152e1..0000000
Binary files a/doc/post-payment.png and /dev/null differ
diff --git a/doc/pre-payment.png b/doc/pre-payment.png
deleted file mode 100644
index e07c072..0000000
Binary files a/doc/pre-payment.png and /dev/null differ
diff --git a/lib/discourse_donations/engine.rb b/lib/discourse_donations/engine.rb
deleted file mode 100644
index 41a41c5..0000000
--- a/lib/discourse_donations/engine.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-module ::DiscourseDonations
- class Engine < ::Rails::Engine
- engine_name 'discourse-donations'
- isolate_namespace DiscourseDonations
- end
-end
diff --git a/lib/discourse_patrons/engine.rb b/lib/discourse_patrons/engine.rb
new file mode 100644
index 0000000..37bc3e0
--- /dev/null
+++ b/lib/discourse_patrons/engine.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module ::DiscoursePatrons
+ PLUGIN_NAME = "discourse-patrons"
+
+ class Engine < ::Rails::Engine
+ engine_name DiscoursePatrons::PLUGIN_NAME
+ isolate_namespace DiscoursePatrons
+ end
+end
diff --git a/plugin.rb b/plugin.rb
index d643306..4e281ed 100644
--- a/plugin.rb
+++ b/plugin.rb
@@ -1,172 +1,15 @@
# frozen_string_literal: true
-# name: discourse-donations
-# about: Integrates Stripe into Discourse to allow visitors to make donations
-# version: 1.12.2
-# url: https://github.com/rimian/discourse-donations
-# authors: Rimian Perkins, Chris Beach, Angus McLeod
+# name: discourse-patrons
+# about: Integrates Stripe into Discourse to allow visitors to make payments
+# version: 1.0.0
+# url: https://github.com/rimian/discourse-patrons
+# authors: Rimian Perkins
-gem 'stripe', '5.1.0'
+enabled_site_setting :discourse_patrons_enabled
-register_asset "stylesheets/common/discourse-donations.scss"
-register_asset "stylesheets/mobile/discourse-donations.scss"
+load File.expand_path('../lib/discourse_patrons/engine.rb', __FILE__)
-enabled_site_setting :discourse_donations_enabled
-
-register_html_builder('server:before-head-close') do
- ""
-end
-
-extend_content_security_policy(
- script_src: ['https://js.stripe.com/v3/']
-)
-
-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
- if custom_fields['stripe_customer_id']
- custom_fields['stripe_customer_id'].to_s
- else
- nil
- end
- end
- end
-
- Category.register_custom_field_type('donations_show_amounts', :boolean)
-
- class ::Category
- def donations_cause
- SiteSetting.discourse_donations_causes_categories.split('|').include? self.id.to_s
- end
-
- def donations_total
- if custom_fields['donations_total']
- custom_fields['donations_total']
- else
- 0
- end
- end
-
- def donations_show_amounts
- if custom_fields['donations_show_amounts'] != nil
- custom_fields['donations_show_amounts']
- else
- false
- end
- end
-
- def donations_month
- if custom_fields['donations_month']
- custom_fields['donations_month']
- else
- 0
- end
- end
-
- def donations_backers
- if custom_fields['donations_backers']
- [*custom_fields['donations_backers']].map do |user_id|
- User.find_by(id: user_id.to_i)
- end
- else
- []
- end
- end
-
- def donations_maintainers
- if custom_fields['donations_maintainers']
- custom_fields['donations_maintainers'].split(',').map do |username|
- User.find_by(username: username)
- end
- else
- []
- end
- end
-
- def donations_maintainers_label
- if custom_fields['donations_maintainers_label']
- custom_fields['donations_maintainers_label']
- else
- nil
- end
- end
-
- def donations_github
- if custom_fields['donations_github']
- custom_fields['donations_github']
- else
- nil
- end
- end
-
- def donations_meta
- if custom_fields['donations_meta']
- custom_fields['donations_meta']
- else
- nil
- end
- end
-
- def donations_release_latest
- if custom_fields['donations_release_latest']
- custom_fields['donations_release_latest']
- else
- nil
- end
- end
-
- def donations_release_oldest
- if custom_fields['donations_release_oldest']
- custom_fields['donations_release_oldest']
- else
- nil
- end
- end
- end
-
- [
- 'donations_cause',
- 'donations_total',
- 'donations_month',
- 'donations_backers',
- 'donations_show_amounts',
- 'donations_maintainers',
- 'donations_maintainers_label',
- 'donations_github',
- 'donations_meta',
- 'donations_release_latest',
- 'donations_release_oldest'
- ].each do |key|
- Site.preloaded_category_custom_fields << key if Site.respond_to? :preloaded_category_custom_fields
- end
-
- add_to_serializer(:basic_category, :donations_cause) { object.donations_cause }
- add_to_serializer(:basic_category, :donations_total) { object.donations_total }
- add_to_serializer(:basic_category, :include_donations_total?) { object.donations_show_amounts }
- add_to_serializer(:basic_category, :donations_month) { object.donations_month }
- add_to_serializer(:basic_category, :include_donations_month?) { object.donations_show_amounts && SiteSetting.discourse_donations_cause_month }
- add_to_serializer(:basic_category, :donations_backers) {
- ActiveModel::ArraySerializer.new(object.donations_backers, each_serializer: BasicUserSerializer).as_json
- }
- add_to_serializer(:basic_category, :donations_maintainers) {
- ActiveModel::ArraySerializer.new(object.donations_maintainers, each_serializer: BasicUserSerializer).as_json
- }
- add_to_serializer(:basic_category, :donations_maintainers_label) { object.donations_maintainers_label }
- add_to_serializer(:basic_category, :include_donations_maintainers_label?) { object.donations_maintainers_label.present? }
- add_to_serializer(:basic_category, :donations_github) { object.donations_github }
- add_to_serializer(:basic_category, :donations_meta) { object.donations_meta }
- add_to_serializer(:basic_category, :donations_release_latest) { object.donations_release_latest }
- add_to_serializer(:basic_category, :donations_release_oldest) { object.donations_release_oldest }
-
- DiscourseEvent.trigger(:donations_ready)
+Discourse::Application.routes.append do
+ mount ::DiscoursePatrons::Engine, at: '/patrons'
end
diff --git a/spec/controllers/discourse_donations/charges_controller_spec.rb b/spec/controllers/discourse_donations/charges_controller_spec.rb
deleted file mode 100644
index edd70f8..0000000
--- a/spec/controllers/discourse_donations/charges_controller_spec.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-shared_examples 'failure response' do |message_key|
- let(:body) { JSON.parse(response.body) }
-
- it 'has status 200' do expect(response).to have_http_status(200) end
- it 'has an error message' do expect(body['messages']).to include(I18n.t(message_key)) end
- it 'is not successful' do expect(body['success']).to eq false end
- it 'does not create a payment' do DiscourseDonations::Stripe.expects(:new).never end
- it 'does not create rewards' do DiscourseDonations::Rewards.expects(:new).never end
- it 'does not queue up any jobs' do ::Jobs.expects(:enqueue).never end
-end
-
-module DiscourseDonations
- RSpec.describe ChargesController, type: :controller do
- routes { DiscourseDonations::Engine.routes }
- let(:body) { JSON.parse(response.body) }
- let(:current_user) { Fabricate(:user) }
- # Workaround for rails-5 issue. See https://github.com/thoughtbot/shoulda-matchers/issues/1018#issuecomment-315876453
- # let(:allowed_params) { { create_account: 'true', email: 'email@example.com', password: 'secret', username: 'mr-pink', name: 'kirsten', amount: 100, stripeToken: 'rrurrrurrrrr' } }
-
- before do
- SiteSetting.stubs(:disable_discourse_narrative_bot_welcome_post).returns(true)
- SiteSetting.stubs(:discourse_donations_secret_key).returns('secret-key-yo')
- SiteSetting.stubs(:discourse_donations_description).returns('charity begins at discourse plugin')
- SiteSetting.stubs(:discourse_donations_currency).returns('AUD')
-
- customer = Fabricate(:stripe_customer).to_json
-
- stub_request(:get, /v1\/customers/).to_return(status: 200, body: customer)
-
- plans = Fabricate(:stripe_plans).to_json
-
- stub_request(:get, "https://api.stripe.com/v1/plans").to_return(status: 200, body: plans)
- stub_request(:post, "https://api.stripe.com/v1/plans").to_return(status: 200, body: plans)
-
- products = Fabricate(:stripe_products).to_json
-
- stub_request(:get, "https://api.stripe.com/v1/products?type=service").to_return(status: 200, body: products)
- stub_request(:post, "https://api.stripe.com/v1/products").to_return(status: 200, body: products)
- stub_request(:post, "https://api.stripe.com/v1/customers").to_return(status: 200, body: customer)
-
- subscription = Fabricate(:stripe_subscription).to_json
-
- stub_request(:post, "https://api.stripe.com/v1/subscriptions").to_return(status: 200, body: subscription)
-
- invoices = Fabricate(:stripe_invoices).to_json
-
- stub_request(:get, "https://api.stripe.com/v1/invoices?customer=cus_FhHJDzf0OxYtb8&subscription=sub_8epEF0PuRhmltU")
- .to_return(status: 200, body: invoices)
- end
-
- xit 'whitelists the params' do
- should permit(:name, :username, :email, :password, :create_account).
- for(:create, params: { params: allowed_params })
- end
-
- it 'responds ok for anonymous users' do
- controller.expects(:current_user).at_least(1).returns(current_user)
-
- post :create, params: { email: 'foobar@example.com' }, format: :json
-
- aggregate_failures do
- expect(response).to have_http_status(200)
- expect(body['messages'][0]).to end_with(I18n.t('donations.payment.success'))
- end
- end
-
- it 'does not expect a username or email if accounts are not being created' do
- charge = Fabricate(:stripe_charge).to_json
- stub_request(:post, "https://api.stripe.com/v1/charges").to_return(status: 200, body: charge)
-
- post :create, params: { create_account: 'false', type: 'once' }, format: :json
-
- aggregate_failures do
- expect(response).to have_http_status(200)
- expect(body['messages'][0]).to end_with(I18n.t('donations.payment.success'))
- end
- end
-
- describe 'create accounts' do
- describe 'create acccount disabled' do
- let(:params) { { amount: 100, stripeToken: 'rrurrrurrrrr-rrruurrrr' } }
-
- before do
- SiteSetting.stubs(:discourse_donations_enable_create_accounts).returns(false)
- ::Jobs.expects(:enqueue).never
- end
-
- it 'does not create user accounts' do
- controller.expects(:current_user).at_least(1).returns(current_user)
-
- post :create, params: params, format: :json
- end
-
- it 'does not create user accounts if the user is logged in' do
- log_in :coding_horror
- post :create, params: params, format: :json
- end
-
- it 'does not create user accounts when settings are disabled and params are not' do
- log_in :coding_horror
- post :create, params: params.merge(create_account: true, email: 'email@example.com', password: 'secret', username: 'mr-brown', name: 'hacker-guy')
- end
- end
-
- describe 'creating an account enabled' do
- let(:params) { { create_account: 'true', email: 'email@example.com', password: 'secret', username: 'mr-pink', amount: 100, stripeToken: 'rrurrrurrrrr-rrruurrrr' } }
-
- before do
- SiteSetting.stubs(:discourse_donations_enable_create_accounts).returns(true)
- Jobs.expects(:enqueue).with(:donation_user, anything)
- end
-
- it 'enqueues the user account create' do
- controller.expects(:current_user).at_least(1).returns(current_user)
-
- post :create, params: params, format: :json
- end
- end
- end
- end
-end
diff --git a/spec/fabricators/charge_fabricator.rb b/spec/fabricators/charge_fabricator.rb
deleted file mode 100644
index 9a08a61..0000000
--- a/spec/fabricators/charge_fabricator.rb
+++ /dev/null
@@ -1,111 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_charge, from: "DiscourseDonations::StripeResponse") do
- response = {
- "id": "ch_1FBxEe2eZvKYlo2CAWyww6QM",
- "object": "charge",
- "amount": 100,
- "amount_refunded": 0,
- "application": "null",
- "application_fee": "null",
- "application_fee_amount": "null",
- "balance_transaction": "txn_19XJJ02eZvKYlo2ClwuJ1rbA",
- "billing_details": {
- "address": {
- "city": "null",
- "country": "null",
- "line1": "null",
- "line2": "null",
- "postal_code": "null",
- "state": "null"
- },
- "email": "null",
- "name": "null",
- "phone": "null"
- },
- "captured": false,
- "created": 1566883732,
- "currency": "usd",
- "customer": "null",
- "description": "My First Test Charge (created for API docs)",
- "destination": "null",
- "dispute": "null",
- "failure_code": "null",
- "failure_message": "null",
- "fraud_details": {},
- "invoice": "null",
- "livemode": false,
- "metadata": {},
- "on_behalf_of": "null",
- "order": "null",
- "outcome": "null",
- "paid": true,
- "payment_intent": "null",
- "payment_method": "card_103Z0w2eZvKYlo2CyzMjT1R1",
- "payment_method_details": {
- "card": {
- "brand": "visa",
- "checks": {
- "address_line1_check": "null",
- "address_postal_code_check": "null",
- "cvc_check": "unchecked"
- },
- "country": "US",
- "exp_month": 2,
- "exp_year": 2015,
- "fingerprint": "Xt5EWLLDS7FJjR1c",
- "funding": "credit",
- "last4": "4242",
- "three_d_secure": "null",
- "wallet": "null"
- },
- "type": "card"
- },
- "receipt_email": "null",
- "receipt_number": "null",
- "receipt_url": "https://pay.stripe.com/receipts/acct_1032D82eZvKYlo2C/ch_1FBxEe2eZvKYlo2CAWyww6QM/rcpt_FhLw6tME6cvwGXWoL0Hn3f65Gkvyocg",
- "refunded": false,
- "refunds": {
- "object": "list",
- "data": [],
- "has_more": false,
- "total_count": 0,
- "url": "/v1/charges/ch_1FBxEe2eZvKYlo2CAWyww6QM/refunds"
- },
- "review": "null",
- "shipping": "null",
- "source": {
- "id": "card_103Z0w2eZvKYlo2CyzMjT1R1",
- "object": "card",
- "address_city": "null",
- "address_country": "null",
- "address_line1": "null",
- "address_line1_check": "null",
- "address_line2": "null",
- "address_state": "null",
- "address_zip": "null",
- "address_zip_check": "null",
- "brand": "Visa",
- "country": "US",
- "customer": "null",
- "cvc_check": "unchecked",
- "dynamic_last4": "null",
- "exp_month": 2,
- "exp_year": 2015,
- "fingerprint": "Xt5EWLLDS7FJjR1c",
- "funding": "credit",
- "last4": "4242",
- "metadata": {},
- "name": "null",
- "tokenization_method": "null"
- },
- "source_transfer": "null",
- "statement_descriptor": "null",
- "statement_descriptor_suffix": "null",
- "status": "succeeded",
- "transfer_data": "null",
- "transfer_group": "null"
- }.to_json
-
- to_json response
-end
diff --git a/spec/fabricators/customer_fabricator.rb b/spec/fabricators/customer_fabricator.rb
deleted file mode 100644
index 6222092..0000000
--- a/spec/fabricators/customer_fabricator.rb
+++ /dev/null
@@ -1,56 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_customer, from: "DiscourseDonations::StripeResponse") do
- response = {
- "id": "cus_FhHJDzf0OxYtb8",
- "object": "customer",
- "account_balance": 0,
- "address": "null",
- "balance": 0,
- "created": 1566866533,
- "currency": "usd",
- "default_source": "null",
- "delinquent": false,
- "description": "null",
- "discount": "null",
- "email": "null",
- "invoice_prefix": "0BBF354",
- "invoice_settings": {
- "custom_fields": "null",
- "default_payment_method": "null",
- "footer": "null"
- },
- "livemode": false,
- "metadata": {},
- "name": "null",
- "phone": "null",
- "preferred_locales": [],
- "shipping": "null",
- "sources": {
- "object": "list",
- "data": [],
- "has_more": false,
- "total_count": 0,
- "url": "/v1/customers/cus_FhHJDzf0OxYtb8/sources"
- },
- "subscriptions": {
- "object": "list",
- "data": [],
- "has_more": false,
- "total_count": 0,
- "url": "/v1/customers/cus_FhHJDzf0OxYtb8/subscriptions"
- },
- "tax_exempt": "none",
- "tax_ids": {
- "object": "list",
- "data": [],
- "has_more": false,
- "total_count": 0,
- "url": "/v1/customers/cus_FhHJDzf0OxYtb8/tax_ids"
- },
- "tax_info": "null",
- "tax_info_verification": "null"
- }.to_json
-
- to_json response
-end
diff --git a/spec/fabricators/invoices_fabricator.rb b/spec/fabricators/invoices_fabricator.rb
deleted file mode 100644
index d4c823c..0000000
--- a/spec/fabricators/invoices_fabricator.rb
+++ /dev/null
@@ -1,128 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_invoices, from: "DiscourseDonations::StripeResponse") do
- response = {
- "object": "list",
- "url": "/v1/invoices",
- "has_more": false,
- "data": [
- {
- "id": "in_1Cc9wc2eZvKYlo2ClBzJbDQz",
- "object": "invoice",
- "account_country": "US",
- "account_name": "Stripe.com",
- "amount_due": 20,
- "amount_paid": 0,
- "amount_remaining": 20,
- "application_fee_amount": "null",
- "attempt_count": 0,
- "attempted": false,
- "auto_advance": false,
- "billing": "send_invoice",
- "billing_reason": "subscription_update",
- "charge": "null",
- "collection_method": "send_invoice",
- "created": 1528800106,
- "currency": "usd",
- "custom_fields": "null",
- "customer": "cus_FhHJDzf0OxYtb8",
- "customer_address": "null",
- "customer_email": "ziad+123@elysian.team",
- "customer_name": "null",
- "customer_phone": "null",
- "customer_shipping": "null",
- "customer_tax_exempt": "none",
- "customer_tax_ids": [],
- "default_payment_method": "null",
- "default_source": "null",
- "default_tax_rates": [],
- "description": "null",
- "discount": "null",
- "due_date": 1529059306,
- "ending_balance": "null",
- "footer": "null",
- "hosted_invoice_url": "null",
- "invoice_pdf": "null",
- "lines": {
- "data": [
- {
- "id": "sli_42e8bf79bec714",
- "object": "line_item",
- "amount": 999,
- "currency": "usd",
- "description": "1 × Ivory Freelance (at $9.99 / month)",
- "discountable": true,
- "livemode": false,
- "metadata": {},
- "period": {
- "end": 1521326190,
- "start": 1518906990
- },
- "plan": {
- "id": "ivory-freelance-040",
- "object": "plan",
- "active": true,
- "aggregate_usage": "null",
- "amount": 999,
- "amount_decimal": "999",
- "billing_scheme": "per_unit",
- "created": 1466202980,
- "currency": "usd",
- "interval": "month",
- "interval_count": 1,
- "livemode": false,
- "metadata": {},
- "nickname": "null",
- "product": "prod_BUthVRQ7KdFfa7",
- "tiers": "null",
- "tiers_mode": "null",
- "transform_usage": "null",
- "trial_period_days": "null",
- "usage_type": "licensed"
- },
- "proration": false,
- "quantity": 1,
- "subscription": "sub_8epEF0PuRhmltU",
- "subscription_item": "si_18NVZi2eZvKYlo2CUtBNGL9x",
- "tax_amounts": [],
- "tax_rates": [],
- "type": "subscription"
- }
- ],
- "has_more": false,
- "object": "list",
- "url": "/v1/invoices/in_1Cc9wc2eZvKYlo2ClBzJbDQz/lines"
- },
- "livemode": false,
- "metadata": {},
- "next_payment_attempt": "null",
- "number": "8B36FE9-0005",
- "paid": false,
- "payment_intent": "null",
- "period_end": 1528800106,
- "period_start": 1528800106,
- "post_payment_credit_notes_amount": 0,
- "pre_payment_credit_notes_amount": 0,
- "receipt_number": "null",
- "starting_balance": 10,
- "statement_descriptor": "null",
- "status": "draft",
- "status_transitions": {
- "finalized_at": "null",
- "marked_uncollectible_at": "null",
- "paid_at": "null",
- "voided_at": "null"
- },
- "subscription": "sub_D2ECXpuEnnXkWU",
- "subtotal": 10,
- "tax": "null",
- "tax_percent": "null",
- "total": 10,
- "total_tax_amounts": [],
- "webhooks_delivered_at": 1528800106
- },
- ]
- }.to_json
-
- to_json response
-end
diff --git a/spec/fabricators/plans_fabricator.rb b/spec/fabricators/plans_fabricator.rb
deleted file mode 100644
index cd4effd..0000000
--- a/spec/fabricators/plans_fabricator.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_plans, from: "DiscourseDonations::StripeResponse") do
- response = {
- "object": "list",
- "url": "/v1/plans",
- "has_more": false,
- "data": [
- {
- "id": "plan_EeE4ns3bvb34ZP",
- "object": "plan",
- "active": true,
- "aggregate_usage": "null",
- "amount": 3000,
- "amount_decimal": "3000",
- "billing_scheme": "per_unit",
- "created": 1551862832,
- "currency": "usd",
- "interval": "month",
- "interval_count": 1,
- "livemode": false,
- "metadata": {},
- "nickname": "Pro Plan",
- "product": "prod_BT942zL7VcClrn",
- "tiers": "null",
- "tiers_mode": "null",
- "transform_usage": "null",
- "trial_period_days": "null",
- "usage_type": "licensed"
- },
- ]
- }.to_json
-
- to_json response
-end
diff --git a/spec/fabricators/products_fabricator.rb b/spec/fabricators/products_fabricator.rb
deleted file mode 100644
index ff9cbcf..0000000
--- a/spec/fabricators/products_fabricator.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_products, from: "DiscourseDonations::StripeResponse") do
- response = {
- "object": "list",
- "url": "/v1/products",
- "has_more": false,
- "data": [
- {
- "id": "prod_FhGJ7clA2xMxGI",
- "object": "product",
- "active": true,
- "attributes": [],
- "caption": "null",
- "created": 1566862775,
- "deactivate_on": [],
- "description": "null",
- "images": [],
- "livemode": false,
- "metadata": {},
- "name": "Sapphire Personal",
- "package_dimensions": "null",
- "shippable": "null",
- "statement_descriptor": "null",
- "type": "service",
- "unit_label": "null",
- "updated": 1566862775,
- "url": "null"
- },
- ]
- }.to_json
-
- to_json response
-end
diff --git a/spec/fabricators/stripe_response.rb b/spec/fabricators/stripe_response.rb
deleted file mode 100644
index 6649fad..0000000
--- a/spec/fabricators/stripe_response.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-# This is for building http responses with Fabricate
-# Usage: Fabricate(:customer).to_json
-# See: https://stripe.com/docs/api
-
-module DiscourseDonations
- class StripeResponse
- attr_accessor :to_json
- end
-end
diff --git a/spec/fabricators/subscription_fabricator.rb b/spec/fabricators/subscription_fabricator.rb
deleted file mode 100644
index 75a716d..0000000
--- a/spec/fabricators/subscription_fabricator.rb
+++ /dev/null
@@ -1,102 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:stripe_subscription, from: "DiscourseDonations::StripeResponse") do
- response = {
- "id": "sub_8epEF0PuRhmltU",
- "object": "subscription",
- "application_fee_percent": "null",
- "billing": "charge_automatically",
- "billing_cycle_anchor": 1466202990,
- "billing_thresholds": "null",
- "cancel_at": "null",
- "cancel_at_period_end": false,
- "canceled_at": 1517528245,
- "collection_method": "charge_automatically",
- "created": 1466202990,
- "current_period_end": 1518906990,
- "current_period_start": 1516228590,
- "customer": "cus_FhHJDzf0OxYtb8",
- "days_until_due": "null",
- "default_payment_method": "null",
- "default_source": "null",
- "default_tax_rates": [],
- "discount": "null",
- "ended_at": 1517528245,
- "items": {
- "object": "list",
- "data": [
- {
- "id": "si_18NVZi2eZvKYlo2CUtBNGL9x",
- "object": "subscription_item",
- "billing_thresholds": "null",
- "created": 1466202990,
- "metadata": {},
- "plan": {
- "id": "ivory-freelance-040",
- "object": "plan",
- "active": true,
- "aggregate_usage": "null",
- "amount": 999,
- "amount_decimal": "999",
- "billing_scheme": "per_unit",
- "created": 1466202980,
- "currency": "usd",
- "interval": "month",
- "interval_count": 1,
- "livemode": false,
- "metadata": {},
- "nickname": "null",
- "product": "prod_BUthVRQ7KdFfa7",
- "tiers": "null",
- "tiers_mode": "null",
- "transform_usage": "null",
- "trial_period_days": "null",
- "usage_type": "licensed"
- },
- "quantity": 1,
- "subscription": "sub_8epEF0PuRhmltU",
- "tax_rates": []
- }
- ],
- "has_more": false,
- "total_count": 1,
- "url": "/v1/subscription_items?subscription=sub_8epEF0PuRhmltU"
- },
- "latest_invoice": "null",
- "livemode": false,
- "metadata": {},
- "pending_setup_intent": "null",
- "plan": {
- "id": "ivory-freelance-040",
- "object": "plan",
- "active": true,
- "aggregate_usage": "null",
- "amount": 999,
- "amount_decimal": "999",
- "billing_scheme": "per_unit",
- "created": 1466202980,
- "currency": "usd",
- "interval": "month",
- "interval_count": 1,
- "livemode": false,
- "metadata": {},
- "nickname": "null",
- "product": "prod_BUthVRQ7KdFfa7",
- "tiers": "null",
- "tiers_mode": "null",
- "transform_usage": "null",
- "trial_period_days": "null",
- "usage_type": "licensed"
- },
- "quantity": 1,
- "schedule": "null",
- "start": 1466202990,
- "start_date": 1466202990,
- "status": "active",
- "tax_percent": "null",
- "trial_end": "null",
- "trial_start": "null"
- }.to_json
-
- to_json response
-end
diff --git a/spec/jobs/regular/donation_user_spec.rb b/spec/jobs/regular/donation_user_spec.rb
deleted file mode 100644
index fa09fea..0000000
--- a/spec/jobs/regular/donation_user_spec.rb
+++ /dev/null
@@ -1,94 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Jobs::DonationUser, type: :job do
- let(:args) { { email: 'captain-sensible@example.com', username: 'wot', name: 'captain', password: 'secret121321' } }
-
- before do
- SiteSetting.stubs(:enable_badges).returns(true)
- end
-
- it 'creates a new user with no rewards' do
- aggregate_failures do
- expect { subject.execute(args) }.to change { User.count }.by(1)
- user = User.find_by_email(args[:email])
- expect(user.badges).to be_empty
- expect(user.groups).to be_empty
- end
- end
-
- describe 'sending the signup email' do
- let(:user) { User.find_by_email(args[:email]) }
-
- it 'has an email token' do
- subject.execute(args)
- expect(user.email_tokens).not_to be_empty
- end
-
- it 'enqueues the signup email' do
- User.expects(:create!).returns(Fabricate(:user, args))
- Jobs.expects(:enqueue).with(
- :critical_user_email,
- type: :signup, user_id: user.id, email_token: user.email_tokens.first.token
- )
- subject.execute(args)
- end
- end
-
- describe 'rewards' do
- describe 'create user with rewards' do
- let(:user) { Fabricate(:user) }
-
- it 'does not create the rewards if the user does not persist' do
- User.expects(:create!).returns(user)
- user.expects(:persisted?).returns(false)
- DiscourseDonations::Rewards.expects(:new).never
- subject.execute(args)
- end
-
- it 'creates a User object without rewards' do
- User.expects(:create!).with(args).returns(user)
- subject.execute(args.merge(rewards: [], otherthing: nil))
- end
- end
-
- describe 'User rewards' do
- let(:user) { Fabricate(:user) }
- let(:badge) { Fabricate(:badge) }
- let(:grp) { Fabricate(:group) }
-
- before do
- User.stubs(:create!).returns(user)
- end
-
- it 'grants the user a badge' do
- subject.execute(args.merge(rewards: [{ type: 'badge', name: badge.name }]))
- aggregate_failures do
- expect(user.badges).to include(badge)
- expect(user.groups).to be_empty
- end
- end
-
- it 'adds the user to the group' do
- subject.execute(args.merge(rewards: [{ type: 'group', name: grp.name }]))
- aggregate_failures do
- expect(user.badges).to be_empty
- expect(user.groups).to include(grp)
- end
- end
-
- it 'has no collisions in badges' do
- Fabricate(:badge, name: 'weiner_schitzel')
- subject.execute(args.merge(rewards: [{ type: 'group', name: 'weiner_schitzel' }]))
- expect(user.badges).to be_empty
- end
-
- it 'has no collisions in groups' do
- Fabricate(:group, name: 'dude_ranch')
- subject.execute(args.merge(rewards: [{ type: 'badge', name: 'dude_ranch' }]))
- expect(user.groups).to be_empty
- end
- end
- end
-end
diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb
deleted file mode 100644
index aa3fb30..0000000
--- a/spec/plugin_helper.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-# frozen_string_literal: true
-
-require_relative './fabricators/charge_fabricator.rb'
-require_relative './fabricators/customer_fabricator.rb'
-require_relative './fabricators/invoices_fabricator.rb'
-require_relative './fabricators/plans_fabricator.rb'
-require_relative './fabricators/products_fabricator.rb'
-require_relative './fabricators/stripe_response.rb'
-require_relative './fabricators/subscription_fabricator.rb'
diff --git a/spec/services/discourse_donations/rewards_spec.rb b/spec/services/discourse_donations/rewards_spec.rb
deleted file mode 100644
index f39956b..0000000
--- a/spec/services/discourse_donations/rewards_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-module DiscourseDonations
- RSpec.describe DiscourseDonations::Rewards do
- let(:grp) { Fabricate(:group) }
- let(:user) { Fabricate(:user) }
- subject { described_class.new(user) }
-
- it 'adds the user to a group' do
- Group.expects(:find_by_name).with(grp.name).returns(grp)
- grp.expects(:add).with(user)
- subject.expects(:log_group_add).once
- subject.add_to_group(grp.name)
- end
-
- it 'does not add the user to a group' do
- Group.expects(:find_by_name).with(grp.name).returns(nil)
- grp.expects(:add).never
- subject.expects(:log_group_add).never
- expect(subject.add_to_group(grp.name)).to be_falsy
- end
-
- it 'logs the group add' do
- GroupActionLogger.any_instance.expects(:log_add_user_to_group)
- subject.add_to_group(grp.name)
- end
-
- describe '.grant_badge' do
- let(:badge) { Fabricate(:badge) }
-
- before { SiteSetting.stubs(:enable_badges).returns(true) }
-
- it 'grants the user a badge' do
- BadgeGranter.expects(:grant).with(badge, user)
- subject.grant_badge(badge.name)
- end
-
- it 'does not grant the user a badge when the badge does not exist' do
- Badge.stubs(:find_by_name).returns(nil)
- BadgeGranter.expects(:grant).never
- expect(subject.grant_badge('does not exist')).to be_falsy
- end
-
- it 'does not grant the user a badge when badges are disabled' do
- SiteSetting.stubs(:enable_badges).returns(false)
- BadgeGranter.expects(:grant).never
- subject.grant_badge(badge.name)
- end
- end
- end
-end
diff --git a/spec/services/discourse_donations/stripe_spec.rb b/spec/services/discourse_donations/stripe_spec.rb
deleted file mode 100644
index f49e1fe..0000000
--- a/spec/services/discourse_donations/stripe_spec.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-require_relative '../../support/dd_helper'
-
-module DiscourseDonations
- RSpec.describe DiscourseDonations::Stripe do
- before { SiteSetting.stubs(:discourse_donations_secret_key).returns('secret-key-yo') }
-
- let(:stripe_options) { { description: 'hi there', currency: 'AUD' } }
- let(:email) { 'ray-zintoast@example.com' }
- let(:customer) { stub(id: 1, email: email) }
- let!(:subject) { described_class.new('secret-key-yo', stripe_options) }
-
- it 'sets the api key' do
- expect(::Stripe.api_key).to eq 'secret-key-yo'
- end
-
- describe 'subscribe' do
- let(:params) { { email: email, stripeToken: 'stripe-token', plan: 'subscription-plan-1234', other: 'redundant param' } }
-
- xit 'creates a customer and a subscription' do
- # todo
-
- ::Stripe::Customer.expects(:create).with(
- email: email,
- source: nil
- ).returns(customer)
-
- ::Stripe::Customer.expects(:list)
-
- subject.subscribe(params)
- end
- end
-
- describe 'charge' do
- let(:params) { { email: email, stripeToken: 'stripe-token', amount: '1234', other: 'redundant param' } }
-
- xit 'creates a customer and charges them an amount' do
- ::Stripe::Customer.expects(:create).with(
- email: email,
- source: 'stripe-token'
- ).returns(customer)
- ::Stripe::Charge.expects(:create).with(
- customer: customer.id,
- amount: params[:amount],
- description: stripe_options[:description],
- currency: stripe_options[:currency]
- ).returns(
- paid: true,
- outcome: { seller_message: 'yay!' }
- )
- subject.charge(nil, params)
- end
- end
-
- describe '.successful?' do
- let(:params) { { email: email, stripeToken: 'stripe-token', amount: '1234', other: 'redundant param' } }
- let(:charge_options) do
- {
- customer: customer.id,
- amount: params[:amount],
- description: stripe_options[:description],
- currency: stripe_options[:currency],
- receipt_email: customer.email,
- metadata: { discourse_cause: nil }
- }
- end
-
- before do
- ::Stripe::Customer.expects(:create).returns(customer)
- end
-
- it 'is successful' do
- ::Stripe::Charge.expects(:create).with(charge_options).returns(paid: true)
-
- ::Stripe::Customer.expects(:list).returns(data: [])
-
- subject.charge(nil, params)
- expect(subject).to be_successful
- end
-
- it 'is not successful' do
- ::Stripe::Charge.expects(:create).with(charge_options).returns(paid: false)
- ::Stripe::Customer.expects(:list).returns(data: [])
- subject.charge(nil, params)
- expect(subject).not_to be_successful
- end
- end
- end
-end
diff --git a/spec/support/dd_helper.rb b/spec/support/dd_helper.rb
deleted file mode 100644
index 051d6fb..0000000
--- a/spec/support/dd_helper.rb
+++ /dev/null
@@ -1,139 +0,0 @@
-# frozen_string_literal: true
-
-require 'fakeweb'
-
-#TODO register some fixtures
-
-FakeWeb.register_uri(:post, 'https://api.stripe.com/v1/customers',
- body: '{
- "id": "cus_AJqrL4OU1sffPl",
- "object": "customer",
- "account_balance": 0,
- "created": 1489965018,
- "currency": "aud",
- "default_source": "card_19zDADEfVxQsvRbHVooMYHqg",
- "delinquent": false,
- "description": null,
- "discount": null,
- "email": "jo@example.com",
- "livemode": false,
- "metadata": {
- },
- "shipping": null,
- "sources": {
- "object": "list",
- "data": [
- {
- "id": "card_19zDADEfVxQsvRbHVooMYHqg",
- "object": "card",
- "address_city": null,
- "address_country": null,
- "address_line1": null,
- "address_line1_check": null,
- "address_line2": null,
- "address_state": null,
- "address_zip": null,
- "address_zip_check": null,
- "brand": "MasterCard",
- "country": "US",
- "customer": "cus_AJqrL4OU1sffPl",
- "cvc_check": "pass",
- "dynamic_last4": null,
- "exp_month": 11,
- "exp_year": 2022,
- "funding": "credit",
- "last4": "4444",
- "metadata": {
- },
- "name": null,
- "tokenization_method": null
- }
- ],
- "has_more": false,
- "total_count": 1,
- "url": "/v1/customers/cus_AJqrL4OU1sffPl/sources"
- }
- }',
- status: ['200', 'OK']
-)
-
-FakeWeb.register_uri(:post, 'https://api.stripe.com/v1/charges',
- body: '{
- "id": "ch_19zDAFEfVxQsvRbHtAwsCvV0",
- "object": "charge",
- "amount": 100,
- "amount_refunded": 0,
- "application": null,
- "application_fee": null,
- "balance_transaction": "txn_19wkkaEfVxQsvRbH8rnq3SAK",
- "captured": true,
- "created": 1489965019,
- "currency": "aud",
- "customer": "cus_AJqrL4OU1sffPl",
- "description": "Donation",
- "destination": null,
- "dispute": null,
- "failure_code": null,
- "failure_message": null,
- "fraud_details": {
- },
- "invoice": null,
- "livemode": false,
- "metadata": {
- },
- "on_behalf_of": null,
- "order": null,
- "outcome": {
- "network_status": "approved_by_network",
- "reason": null,
- "risk_level": "normal",
- "seller_message": "Payment complete.",
- "type": "authorized"
- },
- "paid": true,
- "receipt_email": null,
- "receipt_number": null,
- "refunded": false,
- "refunds": {
- "object": "list",
- "data": [
-
- ],
- "has_more": false,
- "total_count": 0,
- "url": "/v1/charges/ch_19zDAFEfVxQsvRbHtAwsCvV0/refunds"
- },
- "review": null,
- "shipping": null,
- "source": {
- "id": "card_19zDADEfVxQsvRbHVooMYHqg",
- "object": "card",
- "address_city": null,
- "address_country": null,
- "address_line1": null,
- "address_line1_check": null,
- "address_line2": null,
- "address_state": null,
- "address_zip": null,
- "address_zip_check": null,
- "brand": "MasterCard",
- "country": "US",
- "customer": "cus_AJqrL4OU1sffPl",
- "cvc_check": "pass",
- "dynamic_last4": null,
- "exp_month": 11,
- "exp_year": 2022,
- "funding": "credit",
- "last4": "4444",
- "metadata": {
- },
- "name": null,
- "tokenization_method": null
- },
- "source_transfer": null,
- "statement_descriptor": null,
- "status": "succeeded",
- "transfer_group": null
- }',
- status: ['200', 'OK']
-)
diff --git a/test/javascripts/components/donation-form-test.es6 b/test/javascripts/components/donation-form-test.es6
deleted file mode 100644
index 3ce0b0d..0000000
--- a/test/javascripts/components/donation-form-test.es6
+++ /dev/null
@@ -1,22 +0,0 @@
-import componentTest from "helpers/component-test";
-
-moduleForComponent("donation-form", { integration: true });
-
-componentTest("donation form has content", {
- template: `{{donation-form}}`,
-
- beforeEach() {
- this.registry.register(
- "component:stripe-card",
- Ember.Component.extend({ tagName: "dummy-component-tag" })
- );
- },
-
- async test(assert) {
- assert.ok(find("#payment-form").length, "The form renders");
- assert.ok(
- find("dummy-component-tag").length,
- "The stripe component renders"
- );
- }
-});
diff --git a/test/javascripts/components/donation-row-test.js.es6 b/test/javascripts/components/donation-row-test.js.es6
deleted file mode 100644
index 045dcc5..0000000
--- a/test/javascripts/components/donation-row-test.js.es6
+++ /dev/null
@@ -1,33 +0,0 @@
-import componentTest from "helpers/component-test";
-
-moduleForComponent("donation-row", { integration: true });
-
-componentTest("donation-row", {
- template: `{{donation-row currency=3 amount=21 period='monthly'}}`,
-
- test(assert) {
- assert.equal(find(".donation-row-currency").text(), "3", "It has currency");
- assert.equal(find(".donation-row-amount").text(), "21", "It has an amount");
- assert.equal(
- find(".donation-row-period").text(),
- "monthly",
- "It has a period"
- );
- }
-});
-
-componentTest("donation-row cancels subscription", {
- template: `{{donation-row currentUser=currentUser subscription=subscription}}`,
-
- beforeEach() {
- this.set("currentUser", true);
- this.set("subscription", true);
- },
-
- async test(assert) {
- assert.ok(
- find(".donation-row-subscription").length,
- "It has a subscription"
- );
- }
-});
diff --git a/test/javascripts/components/stripe-card-test.js.es6 b/test/javascripts/components/stripe-card-test.js.es6
deleted file mode 100644
index 0dc1e47..0000000
--- a/test/javascripts/components/stripe-card-test.js.es6
+++ /dev/null
@@ -1,33 +0,0 @@
-import componentTest from "helpers/component-test";
-
-moduleForComponent("stripe-card", { integration: true });
-
-window.Stripe = function() {
- return {
- elements: function() {
- return {
- create: function() {
- return {
- mount: function() {},
- card: function() {}
- };
- }
- };
- }
- };
-};
-
-componentTest("stripe card", {
- template: `{{stripe-card donateAmounts=donateAmounts}}`,
-
- skip: true,
-
- beforeEach() {
- Discourse.SiteSettings.discourse_donations_types = "";
- this.set("donateAmounts", [{ value: 2 }]);
- },
-
- test(assert) {
- assert.ok(true);
- }
-});