From 1c9a4399e06c4866cf6661186a5436e140556a99 Mon Sep 17 00:00:00 2001 From: Nazar Gargol Date: Wed, 4 Mar 2020 13:31:39 +0800 Subject: [PATCH] Added support for setting custom currency on member's plans refs c0512e30bb6e5e3f2d3d86a3ca04b0273d405447 - Adds a dropdown allowing to select and set custom currency. - At the moment we don't have a specific way to interface with the members configuration API so all values are set directly on existing "config JSON". Ideally we should add more validations and be more precise what values can be set for the `stripeProcessor.config.*` values. - Saves selected currency in `stripeProcessor.config.currency` variable. --- .../app/components/gh-member-settings-form.js | 2 +- .../app/components/gh-members-lab-setting.js | 60 ++++++++++++++++++- .../components/gh-member-settings-form.hbs | 2 +- .../components/gh-members-lab-setting.hbs | 27 +++++++-- 4 files changed, 82 insertions(+), 9 deletions(-) diff --git a/ghost/admin/app/components/gh-member-settings-form.js b/ghost/admin/app/components/gh-member-settings-form.js index 51078898e2..08f1cbca53 100644 --- a/ghost/admin/app/components/gh-member-settings-form.js +++ b/ghost/admin/app/components/gh-member-settings-form.js @@ -37,7 +37,7 @@ export default Component.extend({ status: subscription.status, startDate: subscription.start_date ? moment(subscription.start_date).format('MMM DD YYYY') : '-', plan: subscription.plan, - dollarAmount: parseInt(subscription.plan.amount) ? (subscription.plan.amount / 100) : 0, + amount: parseInt(subscription.plan.amount) ? (subscription.plan.amount / 100) : 0, cancelAtPeriodEnd: subscription.cancel_at_period_end, validUntil: subscription.current_period_end ? moment(subscription.current_period_end).format('MMM DD YYYY') : '-' }; diff --git a/ghost/admin/app/components/gh-members-lab-setting.js b/ghost/admin/app/components/gh-members-lab-setting.js index 3ac6b8e201..0c97efa3a6 100644 --- a/ghost/admin/app/components/gh-members-lab-setting.js +++ b/ghost/admin/app/components/gh-members-lab-setting.js @@ -7,13 +7,40 @@ import {set} from '@ember/object'; const US = {flag: 'πŸ‡ΊπŸ‡Έ', name: 'US', baseUrl: 'https://api.mailgun.net/v3'}; const EU = {flag: 'πŸ‡ͺπŸ‡Ί', name: 'EU', baseUrl: 'https://api.eu.mailgun.net/v3'}; +const CURRENCIES = [ + { + label: 'USD - US Dollar', value: 'usd' + }, + { + label: 'AUD - Australian Dollar', value: 'aud' + }, + { + label: 'CAD - Canadian Dollar', value: 'cad' + }, + { + label: 'EUR - Euro', value: 'eur' + }, + { + label: 'GBP - British Pound', value: 'gbp' + } +]; + export default Component.extend({ feature: service(), config: service(), mediaQueries: service(), + currencies: null, + + // passed in actions + setMembersSubscriptionSettings() {}, + defaultContentVisibility: reads('settings.defaultContentVisibility'), + selectedCurrency: computed('subscriptionSettings.stripeConfig.plans.monthly.currency', function () { + return CURRENCIES.findBy('value', this.get('subscriptionSettings.stripeConfig.plans.monthly.currency')); + }), + mailgunRegion: computed('settings.bulkEmailSettings.baseUrl', function () { if (!this.settings.get('bulkEmailSettings.baseUrl')) { return US; @@ -37,8 +64,12 @@ export default Component.extend({ }); let monthlyPlan = stripeProcessor.config.plans.find(plan => plan.interval === 'month'); let yearlyPlan = stripeProcessor.config.plans.find(plan => plan.interval === 'year'); - monthlyPlan.dollarAmount = parseInt(monthlyPlan.amount) ? (monthlyPlan.amount / 100) : 0; - yearlyPlan.dollarAmount = parseInt(yearlyPlan.amount) ? (yearlyPlan.amount / 100) : 0; + + // NOTE: need to be careful about division by zero if we introduce zero decimal currencies + // ref.: https://stripe.com/docs/currencies#zero-decimal + monthlyPlan.amount = parseInt(monthlyPlan.amount) ? (monthlyPlan.amount / 100) : 0; + yearlyPlan.amount = parseInt(yearlyPlan.amount) ? (yearlyPlan.amount / 100) : 0; + stripeProcessor.config.plans = { monthly: monthlyPlan, yearly: yearlyPlan @@ -64,12 +95,14 @@ export default Component.extend({ init() { this._super(...arguments); this.set('mailgunRegions', [US, EU]); + this.set('currencies', CURRENCIES); }, actions: { setDefaultContentVisibility(value) { this.setDefaultContentVisibility(value); }, + setBulkEmailSettings(key, event) { let bulkEmailSettings = this.get('settings.bulkEmailSettings') || {}; bulkEmailSettings[key] = event.target.value; @@ -78,11 +111,13 @@ export default Component.extend({ } this.setBulkEmailSettings(bulkEmailSettings); }, + setBulkEmailRegion(region) { let bulkEmailSettings = this.get('settings.bulkEmailSettings') || {}; set(bulkEmailSettings, 'baseUrl', region.baseUrl); this.setBulkEmailSettings(bulkEmailSettings); }, + setSubscriptionSettings(key, event) { let subscriptionSettings = this.settings.parseSubscriptionSettings(this.get('settings.membersSubscriptionSettings')); let stripeProcessor = subscriptionSettings.paymentProcessors.find((proc) => { @@ -113,6 +148,27 @@ export default Component.extend({ if (key === 'fromAddress') { subscriptionSettings.fromAddress = event.target.value; } + + if (key === 'currency') { + stripeProcessor.config.plans.forEach((plan) => { + if (plan.name !== 'Complimentary') { + plan.currency = event.value; + } + }); + + // NOTE: need to keep Complimentary plans with all available currencies so they don't conflict + // when applied to members with existing subscriptions in different currencies (ref. https://stripe.com/docs/billing/customer#currency) + let currentCurrencyComplimentary = stripeProcessor.config.plans.filter(plan => (plan.currency === event.value && plan.name === 'Complimentary')); + + if (!currentCurrencyComplimentary.length) { + let complimentary = stripeProcessor.config.plans.find(plan => (plan.name === 'Complimentary')); + let newComplimentary = Object.assign({}, complimentary, {currency: event.value}); + stripeProcessor.config.plans.push(newComplimentary); + } + + stripeProcessor.config.currency = event.value; + } + this.setMembersSubscriptionSettings(subscriptionSettings); } } diff --git a/ghost/admin/app/templates/components/gh-member-settings-form.hbs b/ghost/admin/app/templates/components/gh-member-settings-form.hbs index 7bd0b21edc..5617361562 100644 --- a/ghost/admin/app/templates/components/gh-member-settings-form.hbs +++ b/ghost/admin/app/templates/components/gh-member-settings-form.hbs @@ -132,7 +132,7 @@ Plan {{subscription.plan.nickname}} - ({{subscription.dollarAmount}} + ({{subscription.amount}} {{subscription.plan.currency}}/{{subscription.plan.interval}}) diff --git a/ghost/admin/app/templates/components/gh-members-lab-setting.hbs b/ghost/admin/app/templates/components/gh-members-lab-setting.hbs index dde0c20585..6092c9b519 100644 --- a/ghost/admin/app/templates/components/gh-members-lab-setting.hbs +++ b/ghost/admin/app/templates/components/gh-members-lab-setting.hbs @@ -65,17 +65,35 @@ {{#liquid-if this.membersPricingOpen}}
+
+ + + + {{one-way-select this.selectedCurrency + id="currency" + name="currency" + options=(readonly this.currencies) + optionValuePath="value" + optionLabelPath="label" + update=(action "setSubscriptionSettings" "currency") + }} + {{svg-jar "arrow-down-small"}} + + +
+
+
- USD/month + {{this.subscriptionSettings.stripeConfig.plans.monthly.currency}}/month
@@ -84,16 +102,15 @@
- USD/year + {{this.subscriptionSettings.stripeConfig.plans.yearly.currency}}/year
-
Currently only USD is supported, more currencies coming soon
{{/liquid-if}}