Files
habitica/website/server/libs/payments/stripe/oneTimePayments.js
Matteo Pagliazzi 6d34319455 Stripe: upgrade module and API, switch to Checkout (#12785)
* upgrade stripe module

* switch stripe api to latest version

* fix api version in tests

* start upgrading client and server

* client: switch to redirect

* implement checkout session creation for gems, start implementing webhooks

* stripe: start refactoring one time payments

* working gems and gift payments

* start adding support for subscriptions

* stripe: migrate subscriptions and fix cancelling sub

* allow upgrading group plans

* remove console.log statements

* group plans: upgrade from static page / create new one

* fix #11885, correct group plan modal title

* silence more stripe webhooks

* fix group plans redirects

* implement editing payment method

* start cleaning up code

* fix(stripe): update in-code docs, fix eslint issues

* subscriptions tests

* remove and skip old tests

* skip integration tests

* fix client build

* stripe webhooks: throw error if request fails

* subscriptions: correctly pass groupId

* remove console.log

* stripe: add unit tests for one time payments

* wip: stripe checkout tests

* stripe createCheckoutSession unit tests

* stripe createCheckoutSession unit tests

* stripe createCheckoutSession unit tests (editing card)

* fix existing webhooks tests

* add new webhooks tests

* add more webhooks tests

* fix lint

* stripe integration tests

* better error handling when retrieving customer from stripe

* client: remove unused strings and improve error handling

* payments: limit gift message length (server)

* payments: limit gift message length (client)

* fix redirects when payment is cancelled

* add back "subUpdateCard" string

* fix redirects when editing a sub card, use proper names for products, check subs when gifting
2020-12-14 15:59:17 +01:00

98 lines
2.8 KiB
JavaScript

import payments from '../payments'; // eslint-disable-line import/no-cycle
import {
BadRequest,
NotAuthorized,
NotFound,
} from '../../errors';
import stripeConstants from './constants';
import shared from '../../../../common';
import { getGemsBlock } from '../gems'; // eslint-disable-line import/no-cycle
import { checkSubData } from './subscriptions'; // eslint-disable-line import/no-cycle
import { model as User } from '../../../models/user'; // eslint-disable-line import/no-cycle
function getGiftAmount (gift) {
if (gift.type === 'subscription') {
return `${shared.content.subscriptionBlocks[gift.subscription.key].price * 100}`;
}
if (gift.gems.amount <= 0) {
throw new BadRequest(shared.i18n.t('badAmountOfGemsToPurchase'));
}
return `${(gift.gems.amount / 4) * 100}`;
}
export async function getOneTimePaymentInfo (gemsBlockKey, gift, user) {
let receiver = user;
if (gift) {
const member = await User.findById(gift.uuid).exec();
if (!member) {
throw new NotFound(shared.i18n.t(
'userWithIDNotFound', { userId: gift.uuid }, user.preferences.language,
));
}
receiver = member;
}
let amount;
let gemsBlock = null;
let subscription = null;
if (gift) {
amount = getGiftAmount(gift);
if (gift.type === 'subscription') {
subscription = shared.content.subscriptionBlocks[gift.subscription.key];
await checkSubData(subscription, false, null);
}
} else {
gemsBlock = getGemsBlock(gemsBlockKey);
amount = gemsBlock.price;
}
if (!gift || gift.type === 'gems') {
const receiverCanGetGems = await receiver.canGetGems();
if (!receiverCanGetGems) throw new NotAuthorized(shared.i18n.t('groupPolicyCannotGetGems', receiver.preferences.language));
}
return {
amount,
gemsBlock,
subscription,
};
}
export async function applyGemPayment (session) {
const { metadata, customer: customerId } = session;
const { gemsBlock: gemsBlockKey, gift: giftStringified, userId } = metadata;
const gemsBlock = gemsBlockKey ? getGemsBlock(gemsBlockKey) : undefined;
const gift = giftStringified ? JSON.parse(giftStringified) : undefined;
const user = await User.findById(metadata.userId).exec();
if (!user) throw new NotFound(shared.i18n.t('userWithIDNotFound', { userId }));
let method = 'buyGems';
const data = {
user,
customerId,
paymentMethod: stripeConstants.PAYMENT_METHOD,
gemsBlock,
gift,
};
if (gift) {
if (gift.type === 'subscription') method = 'createSubscription';
data.paymentMethod = 'Gift';
const member = await User.findById(gift.uuid).exec();
if (!member) {
throw new NotFound(shared.i18n.t('userWithIDNotFound', { userId: gift.uuid }));
}
gift.member = member;
}
await payments[method](data);
}