import { stripe } from '../context/stripe' import { prisma } from '../context/prisma' import { ses } from '../context/aws' import { updateUserAttributes } from '../utils/cognito'; // import * as R from 'colay/ramda'; export const createStripePaths = ({ apiRouter }) => { apiRouter.get('/startSubscription', async (req, res) => { const { query: { sourceId, stripeId, planId, username, } } = req // Attach the card to the user const source = await stripe.customers.createSource(stripeId, { source: sourceId }); if (!source) { throw new Error('Stripe failed to attach card'); } // Subscribe the user to the plan const sub = await stripe.subscriptions.create({ customer: stripeId, items: [{ plan: planId }] }); await updateUserAttributes({ username, attributes: { subscriptionStatus: sub.status, subscriptionId: sub.id, subscriptionItemId: sub.items.data[0].id } }) res.send('ok') }) apiRouter.post('/userCreated', async (req, res) => { const { body: { userAttributes, userName } } = req if (userAttributes.email) { try { await sendEmail(userAttributes.email, "Congratulations " + userName + ", you have been confirmed: "); console.log("===EMAIL SENT==="); } catch (error) { console.log(error); } try { await createAccount(event) } catch (error) { console.log(error); } // callback(null, event); } else { // Nothing to do, the user's email ID is unknown // callback(null, event); } }) apiRouter.post('/updateUsage', async (req, res) => { const { body: { username, itemId }, } = req await (stripe as any).usageRecords.create( itemId, { quantity: 1, timestamp: (Date.now() / 1000) | 0, action: 'increment' }, { idempotency_key: ''//R.uuid() } ); res.send('ok') }) apiRouter.get('/create-checkout-session', async (req, res) => { const { query: { customerId, priceId } } = req console.log('AA', customerId, priceId) const session = await stripe.checkout.sessions.create({ customer: customerId, line_items: [ { // TODO: replace this with the `price` of the product you want to sell price: priceId, quantity: 1, }, ], payment_method_types: [ 'card', ], mode: 'subscription', // automatic_tax: {enabled: true}, success_url: `${process.env.CALLBACK_URL}/stripe-webhook`, cancel_url: `${process.env.CALLBACK_URL}/stripe-webhook`, }); res.redirect(303, session.url) }); apiRouter.post( "/stripe-webhook", async (req, res) => { // Retrieve the event by verifying the signature using the raw body and secret. let event; const { secret_key } = getKeys(); const stripe = new Stripe(secret_key, { apiVersion: "2020-08-27", typescript: true }); // console.log('webhook!', req); try { event = stripe.webhooks.constructEvent( req.body, req.headers["stripe-signature"] || [], stripeWebhookSecret ); } catch (err) { console.log(`⚠️ Webhook signature verification failed.`); res.sendStatus(400); return; } // Extract the data from the event. const data = event.data; const eventType = event.type; if (eventType === "payment_intent.succeeded") { // Cast the event into a PaymentIntent to make use of the types. const pi = data.object; // Funds have been captured // Fulfill any orders, e-mail receipts, etc // To cancel the payment after capture you will need to issue a Refund (https://stripe.com/docs/api/refunds). console.log(`🔔 Webhook received: ${pi.object} ${pi.status}!`); console.log("💰 Payment captured!"); } if (eventType === "payment_intent.payment_failed") { // Cast the event into a PaymentIntent to make use of the types. const pi = data.object; console.log(`🔔 Webhook received: ${pi.object} ${pi.status}!`); console.log("❌ Payment failed."); } if (eventType === "setup_intent.setup_failed") { console.log(`🔔 A SetupIntent has failed the to setup a PaymentMethod.`); } if (eventType === "setup_intent.succeeded") { console.log( `🔔 A SetupIntent has successfully setup a PaymentMethod for future use.` ); } if (eventType === "setup_intent.created") { const setupIntent = data.object; console.log(`🔔 A new SetupIntent is created. ${setupIntent.id}`); } res.sendStatus(200); } ); } const sendEmail= async (to, body) =>{ var eParams = { Destination: { ToAddresses: [to] }, Message: { Body: { Text: { Data: body } }, Subject: { Data: "Cognito Identity Provider registration completed" } }, // Replace source_email with your SES validated email address Source: process.env.SOURCE_EMAIL }; await ses.sendEmail(eParams).promise(); }; const createAccount = async (event) => { const { request: { userAttributes: { uid, email, username, name, phone, }, UserPoolId }, } = event const customer = await stripe.customers.create({ metadata: { uid }, email: email, name, phone, }); const stripeId = customer.id await updateUserAttributes({ username, attributes: { stripeId } }) return prisma.user.create({ data: { email: email, id: uid, name, username, stripeId } }) }