mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Added a validation for a minimum suggested amount for Tips & Donations (#17653)
closes https://github.com/TryGhost/Product/issues/3695 - Stripe has minimum charge amounts per currency, see https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts - We double these limits in our validation, to take into account currency conversions to the main currency used on the Stripe account. If the publishers enters a suggested amount below the limit, they will see an error in Admin - 0 is permitted as default value and corresponds to "no suggested amount"
This commit is contained in:
parent
d24b41f99f
commit
99a9dea988
3 changed files with 58 additions and 1 deletions
|
@ -73,7 +73,11 @@
|
||||||
@class="gh-btn gh-btn-black gh-btn-icon" />
|
@class="gh-btn gh-btn-black gh-btn-icon" />
|
||||||
</div>
|
</div>
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{{#if this.tipsAndDonationsError}}
|
||||||
|
<p class="gh-setting-error"><span class="red">{{this.tipsAndDonationsError}}</span></p>
|
||||||
|
{{/if}}
|
||||||
</GhFormGroup>
|
</GhFormGroup>
|
||||||
</div>
|
</div>
|
||||||
{{/liquid-if}}
|
{{/liquid-if}}
|
||||||
|
|
|
@ -2,10 +2,11 @@ import Component from '@glimmer/component';
|
||||||
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
|
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
|
||||||
import envConfig from 'ghost-admin/config/environment';
|
import envConfig from 'ghost-admin/config/environment';
|
||||||
import {action} from '@ember/object';
|
import {action} from '@ember/object';
|
||||||
import {currencies} from 'ghost-admin/utils/currency';
|
import {currencies, getSymbol, minimumAmountForCurrency} from 'ghost-admin/utils/currency';
|
||||||
import {inject} from 'ghost-admin/decorators/inject';
|
import {inject} from 'ghost-admin/decorators/inject';
|
||||||
import {inject as service} from '@ember/service';
|
import {inject as service} from '@ember/service';
|
||||||
import {task, timeout} from 'ember-concurrency';
|
import {task, timeout} from 'ember-concurrency';
|
||||||
|
import {tracked} from '@glimmer/tracking';
|
||||||
|
|
||||||
const CURRENCIES = currencies.map((currency) => {
|
const CURRENCIES = currencies.map((currency) => {
|
||||||
return {
|
return {
|
||||||
|
@ -20,6 +21,7 @@ export default class TipsAndDonations extends Component {
|
||||||
@service membersUtils;
|
@service membersUtils;
|
||||||
|
|
||||||
@inject config;
|
@inject config;
|
||||||
|
@tracked tipsAndDonationsError = '';
|
||||||
|
|
||||||
get allCurrencies() {
|
get allCurrencies() {
|
||||||
return CURRENCIES;
|
return CURRENCIES;
|
||||||
|
@ -58,7 +60,16 @@ export default class TipsAndDonations extends Component {
|
||||||
setDonationsSuggestedAmount(event) {
|
setDonationsSuggestedAmount(event) {
|
||||||
const amount = Math.abs(event.target.value);
|
const amount = Math.abs(event.target.value);
|
||||||
const amountInCents = Math.round(amount * 100);
|
const amountInCents = Math.round(amount * 100);
|
||||||
|
const currency = this.settings.donationsCurrency;
|
||||||
|
const symbol = getSymbol(currency);
|
||||||
|
const minimumAmount = minimumAmountForCurrency(currency);
|
||||||
|
|
||||||
|
if (amountInCents !== 0 && amountInCents < minimumAmount) {
|
||||||
|
this.tipsAndDonationsError = `The suggested amount cannot be less than ${symbol}${minimumAmount / 100}.`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tipsAndDonationsError = '';
|
||||||
this.settings.donationsSuggestedAmount = amountInCents;
|
this.settings.donationsSuggestedAmount = amountInCents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -162,3 +162,45 @@ export function getCurrencyOptions() {
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the minimum charge amount for a given currency,
|
||||||
|
* based on Stripe's requirements. Values here are double the Stripe limits, to take conversions to the settlement currency into account.
|
||||||
|
* @see https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts
|
||||||
|
* @param {String} currency — Currency in the 3-letter ISO format (e.g. "USD", "EUR")
|
||||||
|
* @retuns {Number} — Minimum amount in cents (e.g. 100 for $1.00)
|
||||||
|
*/
|
||||||
|
export function minimumAmountForCurrency(currency) {
|
||||||
|
switch (currency) {
|
||||||
|
case 'AED':
|
||||||
|
return 400;
|
||||||
|
case 'BGN':
|
||||||
|
return 200;
|
||||||
|
case 'CZK':
|
||||||
|
return 3000;
|
||||||
|
case 'DKK':
|
||||||
|
return 500;
|
||||||
|
case 'HKD':
|
||||||
|
return 800;
|
||||||
|
case 'HUF':
|
||||||
|
return 25000;
|
||||||
|
case 'JPY':
|
||||||
|
return 10000;
|
||||||
|
case 'MXN':
|
||||||
|
return 2000;
|
||||||
|
case 'MYR':
|
||||||
|
return 400;
|
||||||
|
case 'NOK':
|
||||||
|
return 600;
|
||||||
|
case 'PLN':
|
||||||
|
return 400;
|
||||||
|
case 'RON':
|
||||||
|
return 400;
|
||||||
|
case 'SEK':
|
||||||
|
return 600;
|
||||||
|
case 'THB':
|
||||||
|
return 2000;
|
||||||
|
default:
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue