1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Server: Add support for promotion codes

This commit is contained in:
Laurent Cozic 2021-10-07 14:19:40 +01:00
parent be01657ef9
commit 5b58811833
2 changed files with 32 additions and 12 deletions

View File

@ -59,7 +59,7 @@
<script>
const urlQuery = new URLSearchParams(location.search);
let subscriptionPeriod = 'monthly';
var stripe = Stripe('{{{stripeConfig.publishableKey}}}');
const stripe = Stripe('{{{stripeConfig.publishableKey}}}');
let checkoutSessionUser = null;
@ -82,9 +82,9 @@
}
var createCheckoutSession = function(priceId) {
const coupon = urlQuery.get('coupon') || '';
const promotionCode = urlQuery.get('promo') || '';
console.info('Creating Stripe session for price:', priceId, 'Coupon:', coupon);
console.info('Creating Stripe session for price:', priceId, 'Promotion code:', promotionCode);
return fetch("{{{stripeConfig.webhookBaseUrl}}}/stripe/createCheckoutSession", {
method: "POST",
@ -92,8 +92,8 @@
"Content-Type": "application/json"
},
body: JSON.stringify({
priceId: priceId,
coupon: coupon,
priceId,
promotionCode,
email: checkoutSessionUser ? checkoutSessionUser.email : '',
})
}).then(async function(result) {

View File

@ -4,7 +4,7 @@ import { RouteType } from '../../utils/types';
import { AppContext } from '../../utils/types';
import { bodyFields } from '../../utils/requestUtils';
import globalConfig from '../../config';
import { ErrorForbidden, ErrorNotFound } from '../../utils/errors';
import { ErrorBadRequest, ErrorForbidden, ErrorNotFound } from '../../utils/errors';
import { Stripe } from 'stripe';
import Logger from '@joplin/lib/Logger';
import getRawBody = require('raw-body');
@ -35,6 +35,7 @@ async function stripeEvent(stripe: Stripe, req: any): Promise<Stripe.Event> {
interface CreateCheckoutSessionFields {
priceId: string;
coupon: string;
promotionCode: string;
email: string;
}
@ -145,15 +146,30 @@ export const postHandlers: PostHandlers = {
};
if (fields.coupon) {
delete checkoutSession.allow_promotion_codes;
checkoutSession.discounts = [
{
coupon: fields.coupon.trim(),
},
];
} else if (fields.promotionCode) {
const p = await stripe.promotionCodes.list({ code: fields.promotionCode });
const codes = p.data;
if (!codes.length) throw new ErrorBadRequest(`Could not find promotion code: ${fields.promotionCode}`);
// Should not be possible in our setup since a unique code is
// created for each customer.
if (codes.length > 1) console.warn(`Found more than one promotion code: ${fields.promotionCode}`);
checkoutSession.discounts = [
{
promotion_code: codes[0].id,
},
];
}
// "You may only specify one of these parameters: allow_promotion_codes, discounts"
if (checkoutSession.discounts) delete checkoutSession.allow_promotion_codes;
if (fields.email) {
checkoutSession.customer_email = fields.email.trim();
@ -184,7 +200,7 @@ export const postHandlers: PostHandlers = {
// # How to test the complete workflow locally
//
// - In website/build.ts, set the env to "dev", then build the website - `npm run watch-website`
// - In website/build.ts, set the env to "dev", then build the website - `npm run watchWebsite`
// - Start the Stripe CLI tool: `stripe listen --forward-to http://joplincloud.local:22300/stripe/webhook`
// - Copy the webhook secret, and paste it in joplin-credentials/server.env (under STRIPE_WEBHOOK_SECRET)
// - Start the local Joplin Server, `npm run start-dev`, running under http://joplincloud.local:22300
@ -422,14 +438,15 @@ const getHandlers: Record<string, StripeRouteHandler> = {
<script>
var stripe = Stripe(${JSON.stringify(stripeConfig().publishableKey)});
var createCheckoutSession = function(priceId) {
var createCheckoutSession = function(priceId, promotionCode) {
return fetch("/stripe/createCheckoutSession", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
priceId: priceId
priceId,
promotionCode,
})
}).then(function(result) {
return result.json();
@ -438,6 +455,7 @@ const getHandlers: Record<string, StripeRouteHandler> = {
</script>
</head>
<body>
Promotion code: <input id="promotion_code" type="text"/> <br/>
<button id="checkout_basic">Subscribe Basic</button>
<button id="checkout_pro">Subscribe Pro</button>
<button id="checkout_custom">Subscribe Custom</button>
@ -455,7 +473,9 @@ const getHandlers: Record<string, StripeRouteHandler> = {
}
function createSessionAndRedirect(priceId) {
createCheckoutSession(priceId).then(function(data) {
var promotionCode = document.getElementById('promotion_code').value;
createCheckoutSession(priceId, promotionCode).then(function(data) {
// Call Stripe.js method to redirect to the new Checkout page
stripe
.redirectToCheckout({