Created
July 21, 2021 17:16
-
-
Save nickfogle/4352b2102e4aee0885ca0a355b22bd68 to your computer and use it in GitHub Desktop.
Churnkey Sample Code for Vue.js Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import moment from 'moment'; | |
import { Notification } from 'element-ui'; | |
import UserService from '@/api/user.service'; | |
import { IS_PRODUCTION } from '@/config'; | |
import store from '@/store'; | |
export default async function launchChurnkey(user) { | |
const customerId = user.stripe.id; | |
try { | |
const { authHash } = await UserService.getChurnKeyHash(customerId); | |
// initialize Churnkey flow | |
window.churnkey.init('show', { | |
appId: 'ikmp8qyfz', | |
customerId, | |
authHash, | |
mode: IS_PRODUCTION ? 'live' : 'test', | |
// sample code for launching intercom support chat when embed button clicked. | |
handleSupportRequest: customer => { | |
window.Intercom('showNewMessage', 'Attention: Offboarding Customer Needs Help ASAP.'); | |
window.churnkey.hide(); | |
}, | |
// sample pause handler (used if you want to handle cancelation instead of letting Churnkey do it | |
handlePause: (customer, options) => { | |
const duration = options.pauseDuration; | |
return new Promise(async (resolve, reject) => { | |
try { | |
await submitPause(user, duration); | |
resolve({ message: 'Account paused.' }); | |
} catch (e) { | |
reject({ message: 'Pause failed. Please reach out to us for help.' }); | |
} | |
}); | |
}, | |
// sample pause handler (used if you want to handle cancelation instead of letting Churnkey do it | |
// params `customer` and `surveyAnswer` are optional if you want to handle cancel and collect the data yourself. | |
handleCancel: (customer, surveyAnswer) | |
return new Promise(async (resolve, reject) => { | |
try { | |
await submitCancel(user, customer.plan); | |
resolve({ message: 'Your account has been canceled.' }); | |
} catch (e) { | |
reject({ message: 'Failed to cancel account. Please reach out to us for help.' }); | |
} | |
}); | |
}, | |
}); | |
} catch (error) { | |
console.log('Error', error); | |
} | |
} | |
async function submitPause(user, duration) { | |
try { | |
// Make API request to custom endpoint for updating stripe as well as DB record. | |
await UserService.updateBilling(user.id, { duration, event: 'pause' }); | |
// sync updated user subscription details to vuex | |
await store.dispatch('SYNC_USER_TO_DB'); | |
Notification.success({ title: 'Success', message: 'Subscription Paused' }); | |
} catch (err) { | |
throw new Error('Could not pause'); | |
} | |
} | |
async function submitCancel(user, plan) { | |
try { | |
await UserService.updateBilling(user.id, { event: 'cancel', plan }); | |
// sync updated user subscription details to vuex and refresh state | |
await store.dispatch('SYNC_USER_TO_DB'); | |
// Notify user of successful cancellation | |
Notification.success({ title: 'Canceled', message: `Access will end on ${planChange.stopDate}.` }); | |
} catch (err) { | |
throw new Error('Could not cancel'); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default function loadChurnKey() { | |
if (!window.churnkey || !window.churnkey.created) { | |
window.churnkey = { created: true }; | |
const a = document.createElement('script'); | |
a.src = 'https://assets.churnkey.co/js/app.js'; | |
a.async = true; | |
const b = document.getElementsByTagName('script')[0]; | |
b.parentNode.insertBefore(a, b); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div> | |
<h1>Billing Summary</h1> | |
<!-- show button if user can cancel and loading finished --> | |
<div> | |
<button id="ck-cancel" @click="cancelFlow()" v-if="user.canCancel && !isLoading">Cancel</el-button> | |
</div> | |
</template> | |
<script> | |
import loadChurnKey from '@/helpers/loadChurnKey'; | |
import launchChurnKey from '@/helpers/launchChurnKey'; | |
export default { | |
name: 'SamplePage', | |
computed: { | |
user() { | |
return this.$store.state.user; | |
}, | |
canCancel() { | |
// hide cancel button if user doesn't have an active subscription | |
return this.user.subscription; | |
}, | |
}, | |
data() { | |
return { | |
isLoading: false, | |
}; | |
}, | |
methods: { | |
// click handler for launching churnkey embed | |
cancelFlow() { | |
launchChurnKey(this.user); | |
}, | |
}, | |
mounted() { | |
const vm = this; | |
loadChurnKey(); | |
}, | |
}; | |
</script> | |
<style> | |
.button { | |
color: #000; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can load the Churnkey 3rd party Javascript on a single page or across your entire application. We find it's best to only load it on the page where you actually need it (example - billing page).
This example code shows you how to do that using vue.js. The
loadChurnkey.js
script allows you to import Churnkey to whatever page or component from which you plan to launch Churnkey. Then, thehandleCustomFlow.js
script shows off a few of the custom callback handlers (options described more fully here: https://docs.churnkey.co/installing-churnkey#efc85982b3364c28b1ebaa7c9d21d7c1).Finally, you'll import both of these scripts into the vue template and then you'll create a click handler for triggering the embed loading.