import { stripe , db , auth } from './config' ; export function authenticateUser ( req , res , next ) { let authToken ; if ( req . headers . authorization && req . headers . authorization . startsWith ( 'Bearer ' ) ) { authToken = req . headers . authorization . split ( 'Bearer ' ) [ 1 ] ; } else { res . status ( 403 ) . send ( 'Must provide a header that looks like "Authorization: Bearer <Firebase ID Token>"' ) ; } auth . verifyIdToken ( authToken ) . then ( decodedToken => { req . user = decodedToken ; next ( ) ; } ) . catch ( err => res . status ( 403 ) . send ( err ) ) ; } export async function getUser ( userId ) { return await db . collection ( 'users' ) . doc ( userId ) . get ( ) . then ( doc => doc . data ( ) ) ; } export async function createCustomer ( firebaseUser ) { return await stripe . customers . create ( { email : firebaseUser . email , metadata : { firebaseUID : firebaseUser . uid } } ) ; } export async function getCustomer ( userId ) { const user = await getUser ( userId ) ; const customerId = user . stripeCustomerId ; return await stripe . customers . retrieve ( customerId ) ; } export async function attachSource ( userId , sourceId ) { const customer = await getCustomer ( userId ) ; const existingSource = customer . sources . data . filter ( source => source . id === sourceId ) . pop ( ) ; if ( existingSource ) { return existingSource ; } else { return await stripe . customers . createSource ( customer . id , { source : sourceId } ) ; } } export async function createCharge ( userId , sourceId , amount , currency ? ) { const user = await getUser ( userId ) ; const customerId = user . stripeCustomerId ; const card = await attachSource ( userId , sourceId ) ; return await stripe . charges . create ( { amount : amount , currency : currency || 'usd' , customer : customerId , source : sourceId } ) ; } export async function getUserCharges ( userId , limit ? ) { const user = await getUser ( userId ) ; const customerId = user . stripeCustomerId ; return await stripe . charges . list ( { limit , customer : customerId } ) ; } export async function createSubscription ( userId , sourceId , planId ) { const user = await getUser ( userId ) ; const customerId = user . stripeCustomerId ; const card = await attachSource ( userId , sourceId ) ; const subscription = await stripe . subscriptions . create ( { customer : customerId , items : [ { plan : planId , } , ] } ) ; const subscriptions = { [ planId ] : 'active' } ; await db . doc ( `users/${ userId }` ) . set ( { subscriptions } , { merge : true } ) ; return subscription ; } export async function cancelSubscription ( userId , planId ) { const subscription = await getSubscription ( userId , planId ) ; let cancellation ; if ( subscription ) { cancellation = await stripe . subscriptions . del ( subscription . id ) ; } const subscriptions = { [ planId ] : 'cancelled' } ; await db . doc ( `users/${ userId }` ) . set ( { subscriptions } , { merge : true } ) ; return cancellation ; } export async function recurringPayment ( customerId , planId , hook ) { const customer = await stripe . customers . retrieve ( customerId ) ; const userId = customer . metadata . firebaseUID ; let status ; if ( hook === 'invoice.payment_succeeded' ) { status = 'active' ; } ; if ( hook === 'invoice.payment_failed' ) { status = 'cancelled' ; } ; const subscriptions = { [ planId ] : status } ; return await db . doc ( `users/${ userId }` ) . set ( { subscriptions } , { merge : true } ) ; } export async function getSubscription ( userId , planId ) { const user = await getUser ( userId ) ; const customer = user . stripeCustomerId ; const stripeSubs = await stripe . subscriptions . list ( { customer , plan : planId } ) ; return stripeSubs . data [ 0 ] ; }