diff --git a/ghost/admin/app/components/gh-members-payments-setting.js b/ghost/admin/app/components/gh-members-payments-setting.js
index c41a97205f..9cb55fb990 100644
--- a/ghost/admin/app/components/gh-members-payments-setting.js
+++ b/ghost/admin/app/components/gh-members-payments-setting.js
@@ -1,30 +1,10 @@
import Component from '@ember/component';
import {computed} from '@ember/object';
+import {currencies} from 'ghost-admin/utils/currency';
import {reads} from '@ember/object/computed';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
-export const CURRENCIES = [
- {
- label: 'USD - US Dollar', value: 'usd', symbol: '$'
- },
- {
- label: 'AUD - Australian Dollar', value: 'aud', symbol: '$'
- },
- {
- label: 'CAD - Canadian Dollar', value: 'cad', symbol: '$'
- },
- {
- label: 'EUR - Euro', value: 'eur', symbol: '€'
- },
- {
- label: 'GBP - British Pound', value: 'gbp', symbol: '£'
- },
- {
- label: 'INR - Indian Rupee', value: 'inr', symbol: '₹'
- }
-];
-
export default Component.extend({
feature: service(),
config: service(),
@@ -47,7 +27,7 @@ export default Component.extend({
stripeDirect: reads('config.stripeDirect'),
allowSelfSignup: reads('settings.membersAllowFreeSignup'),
-
+
/** OLD **/
stripeDirectPublicKey: reads('settings.stripePublishableKey'),
stripeDirectSecretKey: reads('settings.stripeSecretKey'),
@@ -59,7 +39,7 @@ export default Component.extend({
portalSettingsBorderColor: reads('settings.accentColor'),
selectedCurrency: computed('stripePlans.monthly.currency', function () {
- return CURRENCIES.findBy('value', this.get('stripePlans.monthly.currency'));
+ return this.get('currencies').findBy('value', this.get('stripePlans.monthly.currency'));
}),
blogDomain: computed('config.blogDomain', function () {
@@ -87,7 +67,13 @@ export default Component.extend({
init() {
this._super(...arguments);
- this.set('currencies', CURRENCIES);
+ this.set('currencies', currencies.map((currency) => {
+ return {
+ value: currency.isoCode.toLowerCase(),
+ label: `${currency.isoCode} - ${currency.name}`,
+ isoCode: currency.isoCode
+ };
+ }));
if (this.get('stripeConnectAccountId')) {
this.set('membersStripeOpen', false);
} else {
@@ -124,45 +110,7 @@ export default Component.extend({
},
validateStripePlans() {
- this.get('settings.errors').remove('stripePlans');
- this.get('settings.hasValidated').removeObject('stripePlans');
-
- if (this._scratchStripeYearlyAmount === null) {
- this._scratchStripeYearlyAmount = this.get('stripePlans').yearly.amount;
- }
- if (this._scratchStripeMonthlyAmount === null) {
- this._scratchStripeMonthlyAmount = this.get('stripePlans').monthly.amount;
- }
-
- try {
- const selectedCurrency = this.selectedCurrency;
- const yearlyAmount = parseInt(this._scratchStripeYearlyAmount);
- const monthlyAmount = parseInt(this._scratchStripeMonthlyAmount);
- if (!yearlyAmount || yearlyAmount < 1 || !monthlyAmount || monthlyAmount < 1) {
- throw new TypeError(`Subscription amount must be at least ${selectedCurrency.symbol}1.00`);
- }
-
- const updatedPlans = this.get('settings.stripePlans').map((plan) => {
- if (plan.name !== 'Complimentary') {
- let newAmount;
- if (plan.interval === 'year') {
- newAmount = yearlyAmount * 100;
- } else if (plan.interval === 'month') {
- newAmount = monthlyAmount * 100;
- }
- return Object.assign({}, plan, {
- amount: newAmount
- });
- }
- return plan;
- });
-
- this.set('settings.stripePlans', updatedPlans);
- } catch (err) {
- this.get('settings.errors').add('stripePlans', err.message);
- } finally {
- this.get('settings.hasValidated').pushObject('stripePlans');
- }
+ this.validateStripePlans();
},
setStripePlansCurrency(event) {
@@ -190,6 +138,9 @@ export default Component.extend({
}
this.set('settings.stripePlans', updatedPlans);
+ this.set('_scratchStripeYearlyAmount', null);
+ this.set('_scratchStripeMonthlyAmount', null);
+ this.validateStripePlans();
},
setStripeConnectIntegrationToken(event) {
@@ -224,6 +175,53 @@ export default Component.extend({
}
},
+ validateStripePlans() {
+ this.get('settings.errors').remove('stripePlans');
+ this.get('settings.hasValidated').removeObject('stripePlans');
+
+ if (this._scratchStripeYearlyAmount === null) {
+ this._scratchStripeYearlyAmount = this.get('stripePlans').yearly.amount;
+ }
+ if (this._scratchStripeMonthlyAmount === null) {
+ this._scratchStripeMonthlyAmount = this.get('stripePlans').monthly.amount;
+ }
+
+ try {
+ const selectedCurrency = this.selectedCurrency;
+ const yearlyAmount = parseInt(this._scratchStripeYearlyAmount);
+ const monthlyAmount = parseInt(this._scratchStripeMonthlyAmount);
+ if (!yearlyAmount || yearlyAmount < 1 || !monthlyAmount || monthlyAmount < 1) {
+ const minimum = Intl.NumberFormat(this.settings.get('lang'), {
+ currency: selectedCurrency.isoCode,
+ style: 'currency'
+ }).format(1);
+
+ throw new TypeError(`Subscription amount must be at least ${minimum}`);
+ }
+
+ const updatedPlans = this.get('settings.stripePlans').map((plan) => {
+ if (plan.name !== 'Complimentary') {
+ let newAmount;
+ if (plan.interval === 'year') {
+ newAmount = yearlyAmount * 100;
+ } else if (plan.interval === 'month') {
+ newAmount = monthlyAmount * 100;
+ }
+ return Object.assign({}, plan, {
+ amount: newAmount
+ });
+ }
+ return plan;
+ });
+
+ this.set('settings.stripePlans', updatedPlans);
+ } catch (err) {
+ this.get('settings.errors').add('stripePlans', err.message);
+ } finally {
+ this.get('settings.hasValidated').pushObject('stripePlans');
+ }
+ },
+
openDisconnectStripeConnectModal: task(function* () {
this.set('hasActiveStripeSubscriptions', false);
if (!this.get('stripeConnectAccountId')) {
diff --git a/ghost/admin/app/utils/currency.js b/ghost/admin/app/utils/currency.js
index 083517e70b..8ae33d4755 100644
--- a/ghost/admin/app/utils/currency.js
+++ b/ghost/admin/app/utils/currency.js
@@ -1,28 +1,130 @@
+export const currencies = [
+ {isoCode: 'AED', name: 'United Arab Emirates dirham'},
+ {isoCode: 'AFN', name: 'Afghan afghani'},
+ {isoCode: 'ALL', name: 'Albanian lek'},
+ {isoCode: 'AMD', name: 'Armenian dram'},
+ {isoCode: 'ANG', name: 'Netherlands Antillean guilder'},
+ {isoCode: 'AOA', name: 'Angolan kwanza'},
+ {isoCode: 'ARS', name: 'Argentine peso'},
+ {isoCode: 'AUD', name: 'Austrialian dollar'},
+ {isoCode: 'AWG', name: 'Aruban florin'},
+ {isoCode: 'AZN', name: 'Azerbaijani manat'},
+ {isoCode: 'BAM', name: 'Bosnia and Herzegovina convertible mark'},
+ {isoCode: 'BBD', name: 'Barbados dollar'},
+ {isoCode: 'BDT', name: 'Bangladeshi taka'},
+ {isoCode: 'BGN', name: 'Bulgarian lev'},
+ {isoCode: 'BMD', name: 'Bermudian dollar'},
+ {isoCode: 'BND', name: 'Brunei dollar'},
+ {isoCode: 'BOB', name: 'Boliviano'},
+ {isoCode: 'BRL', name: 'Brazilian real'},
+ {isoCode: 'BSD', name: 'Bahamian dollar'},
+ {isoCode: 'BWP', name: 'Botswana pula'},
+ {isoCode: 'BZD', name: 'Belize dollar'},
+ {isoCode: 'CAD', name: 'Canadian dollar'},
+ {isoCode: 'CDF', name: 'Congolese franc'},
+ {isoCode: 'CHF', name: 'Swiss franc'},
+ {isoCode: 'CNY', name: 'Chinese yuan'},
+ {isoCode: 'COP', name: 'Colombian peso'},
+ {isoCode: 'CRC', name: 'Costa Rican colon'},
+ {isoCode: 'CVE', name: 'Cape Verdean escudo'},
+ {isoCode: 'CZK', name: 'Czech koruna'},
+ {isoCode: 'DKK', name: 'Danish krone'},
+ {isoCode: 'DOP', name: 'Dominican peso'},
+ {isoCode: 'DZD', name: 'Algerian dinar'},
+ {isoCode: 'EGP', name: 'Egyptian pound'},
+ {isoCode: 'ETB', name: 'Ethiopian birr'},
+ {isoCode: 'EUR', name: 'Euro'},
+ {isoCode: 'FJD', name: 'Fiji dollar'},
+ {isoCode: 'FKP', name: 'Falkland Islands pound'},
+ {isoCode: 'GBP', name: 'Pound sterling'},
+ {isoCode: 'GEL', name: 'Georgian lari'},
+ {isoCode: 'GIP', name: 'Gibraltar pound'},
+ {isoCode: 'GMD', name: 'Gambian dalasi'},
+ {isoCode: 'GTQ', name: 'Guatemalan queztal'},
+ {isoCode: 'GYD', name: 'Guyanese dollar'},
+ {isoCode: 'HKD', name: 'Hong Kong dollar'},
+ {isoCode: 'HNL', name: 'Honduran lempira'},
+ {isoCode: 'HRK', name: 'Croation kuna'},
+ {isoCode: 'HTG', name: 'Haitian gourde'},
+ {isoCode: 'HUF', name: 'Hungarian forint'},
+ {isoCode: 'IDR', name: 'Indonesian rupiah'},
+ {isoCode: 'ILS', name: 'Israeli new shekel'},
+ {isoCode: 'INR', name: 'Indian rupee'},
+ {isoCode: 'ISK', name: 'Icelandic króna'},
+ {isoCode: 'JMD', name: 'Jamaican dollar'},
+ {isoCode: 'KES', name: 'Kenyan shilling'},
+ {isoCode: 'KGS', name: 'Kyrgyzstani som'},
+ {isoCode: 'KHR', name: 'Cambodian riel'},
+ {isoCode: 'KYD', name: 'Cayman Islands dollar'},
+ {isoCode: 'KZT', name: 'Kazakhstani tenge'},
+ {isoCode: 'LAK', name: 'Lao kip'},
+ {isoCode: 'LBP', name: 'Lebanese pound'},
+ {isoCode: 'LKR', name: 'Sri Lankan rupee'},
+ {isoCode: 'LRD', name: 'Liberian dollar'},
+ {isoCode: 'LSL', name: 'Lesotho loti'},
+ {isoCode: 'MAD', name: 'Moroccan dirham'},
+ {isoCode: 'MDL', name: 'Moldovan leu'},
+ {isoCode: 'MKD', name: 'Macedonian denar'},
+ {isoCode: 'MMK', name: 'Myanmar kyat'},
+ {isoCode: 'MNT', name: 'Mongolian tögrög'},
+ {isoCode: 'MOP', name: 'Macanese pataca'},
+ {isoCode: 'MRO', name: 'Mauritanian ouguiya'},
+ {isoCode: 'MUR', name: 'Mauritian rupee'},
+ {isoCode: 'MVR', name: 'Maldivian rufiyaa'},
+ {isoCode: 'MWK', name: 'Malawian kwacha'},
+ {isoCode: 'MXN', name: 'Mexican peso'},
+ {isoCode: 'MYR', name: 'Malaysian ringgit'},
+ {isoCode: 'MZN', name: 'Mozambican metical'},
+ {isoCode: 'NAD', name: 'Namibian dollar'},
+ {isoCode: 'NGN', name: 'Nigerian naira'},
+ {isoCode: 'NIO', name: 'Nicaraguan córdoba'},
+ {isoCode: 'NOK', name: 'Norwegian krone'},
+ {isoCode: 'NPR', name: 'Nepalese rupee'},
+ {isoCode: 'NZD', name: 'New Zealand dollar'},
+ {isoCode: 'PAB', name: 'Panamanian balboa'},
+ {isoCode: 'PEN', name: 'Peruvian sol'},
+ {isoCode: 'PGK', name: 'Papua New Guinean kina'},
+ {isoCode: 'PHP', name: 'Philippine peso'},
+ {isoCode: 'PKR', name: 'Pakistani rupee'},
+ {isoCode: 'PLN', name: 'Polish złoty'},
+ {isoCode: 'QAR', name: 'Qatari riyal'},
+ {isoCode: 'RON', name: 'Romanian leu'},
+ {isoCode: 'RSD', name: 'Serbian dinar'},
+ {isoCode: 'RUB', name: 'Russian ruble'},
+ {isoCode: 'SAR', name: 'Saudi riyal'},
+ {isoCode: 'SBD', name: 'Solomon Islands dollar'},
+ {isoCode: 'SCR', name: 'Seychelles rupee'},
+ {isoCode: 'SEK', name: 'Swedish krona'},
+ {isoCode: 'SGD', name: 'Singapore dollar'},
+ {isoCode: 'SHP', name: 'Saint Helena pound'},
+ {isoCode: 'SLL', name: 'Sierra Leonean leone'},
+ {isoCode: 'SOS', name: 'Somali shilling'},
+ {isoCode: 'SRD', name: 'Surinamese dollar'},
+ {isoCode: 'STD', name: 'São Tomé and Príncipe dobra'},
+ {isoCode: 'SZL', name: 'Salvadoran colón'},
+ {isoCode: 'THB', name: 'Thai baht'},
+ {isoCode: 'TJS', name: 'Tajikistani somoni'},
+ {isoCode: 'TOP', name: 'Tongan paʻanga'},
+ {isoCode: 'TRY', name: 'Turkish lira'},
+ {isoCode: 'TTD', name: 'Trinidad and Tobago dollar'},
+ {isoCode: 'TWD', name: 'New Taiwan dollar'},
+ {isoCode: 'TZS', name: 'Tanzanian shilling'},
+ {isoCode: 'UAH', name: 'Ukrainian hryvnia'},
+ {isoCode: 'USD', name: 'United States dollar'},
+ {isoCode: 'UYU', name: 'Uruauayan peso'},
+ {isoCode: 'UZS', name: 'Uzbekistan som'},
+ {isoCode: 'WST', name: 'Samoan tala'},
+ {isoCode: 'XCD', name: 'East Caribbean dollar'},
+ {isoCode: 'YER', name: 'Yemeni rial'},
+ {isoCode: 'ZAR', name: 'South African rand'},
+ {isoCode: 'ZMW', name: 'Zambian kwacha'}
+];
+
export function getSymbol(currency) {
- switch (currency) {
- case 'usd':
- case 'aud':
- case 'cad':
- return '$';
- case 'eur':
- return '€';
- case 'gbp':
- return '£';
- case 'inr':
- return '₹';
- }
- return null;
+ return Intl.NumberFormat('en', {currency, style: 'currency'}).format(0).replace(/[\d\s.]/g, '');
}
-export function getNonDecimal(amount, currency) {
- switch (currency) {
- case 'usd':
- case 'aud':
- case 'cad':
- case 'eur':
- case 'gbp':
- case 'inr':
- return amount / 100;
- }
- return null;
+// We currently only support decimal currencies
+export function getNonDecimal(amount/*, currency*/) {
+ return amount / 100;
}