Commit 372c7853 authored by Aral Balkan's avatar Aral Balkan

Refactor to pull out payment-related (model) logic into its own class

parent 144d3bcb
......@@ -15,6 +15,76 @@ NodeList.prototype.forEach = Array.prototype.forEach
const $ = document.querySelector.bind(document)
const $$ = document.querySelectorAll.bind(document)
class Payment {
// Static properties.
static get UNKNOWN_HOST_ERROR () { return `unknown host (not specified as test host or live host): ${this.host}` }
static get testHosts () { return ['localhost', 'dev.ar.al'] }
static get liveHost () { return 'small-tech.org' }
static get testKey () { return 'pk_test_mLQRpGuO7qq3XMfSgwmt4n8U00FSZOIY1h' }
static get liveKey () { return '<TODO: Stripe live key>' }
constructor () {
this.host = window.location.hostname
}
// Instance properties.
get stripe () {
if (this._stripe === undefined) {
this._stripe = Stripe(this.publicKey)
}
return this._stripe
}
get isTestHost () { return Payment.testHosts.includes(this.host) }
get isLiveHost () { return this.host === Payment.liveHost }
get publicKey () {
if (this.isTestHost) return Payment.testKey
if (this.isLiveHost) return Payment.liveKey
throw new Error(Payment.UNKNOWN_HOST_ERROR)
}
get items () {
if (this.isTestHost) {
return this.payment.isPatronage ?
[{plan: 'plan_FSsO2vwva5oEOP', quantity: this.payment.amount}] :
[{sku: 'sku_FVm0elVvrMW0sX', quantity: this.payment.amount}]
} else if (this.isLiveHost) {
return this.payment.isPatronage ?
[{plan: '<TODO: Live patronage plan>', quantity: this.payment.amount}] :
[{sku: '<TODO: Live donation SKU>', quantity: this.payment.amount}]
} else {
throw new Error(Payment.UNKNOWN_HOST_ERROR)
}
}
get successUrl () {
return this.payment.isPatronage ?
`https://${this.host}/patronage/?id={CHECKOUT_SESSION_ID}` :
`https://${this.host}/fund-us/thank-you`
}
get cancelUrl () { return `https://${this.host}/fund-us/cancel` }
get stripePaymentDetails () {
return {
items: this.items,
successUrl: this.successUrl,
cancelUrl: this.cancelUrl
}
}
async redirectToCheckout (payment) {
this.payment = payment
return await this.stripe.redirectToCheckout(this.stripePaymentDetails)
}
}
class PatronageForm {
static get CUSTOM_DONATION_AMOUNT () { return -1 }
......@@ -22,9 +92,7 @@ class PatronageForm {
constructor () {
window.addEventListener('load', this.setInitialInterfaceState.bind(this))
// TODO: Set key based on hostname.
this.stripe = Stripe('pk_test_mLQRpGuO7qq3XMfSgwmt4n8U00FSZOIY1h')
this.payment = new Payment()
}
......@@ -46,7 +114,7 @@ class PatronageForm {
}
//
// Handle all interface events as a state update.
// Handle all interface events in a single state update method.
//
const updateFormState = this.updateFormState.bind(this)
......@@ -87,9 +155,6 @@ class PatronageForm {
// Updates form state in response to interface events.
updateFormState () {
console.log('<<< update form state >>>')
// Handle the label of the submit button based on the type of donation.
this.interface.submitButton.innerHTML = this.isPatronage ? 'Become a patron' : 'Donate'
......@@ -125,33 +190,13 @@ class PatronageForm {
}
// Redirects to Stripe checkout.
async redirectToCheckout () {
const host = `https://${window.location.hostname}`
const stripeRedirect = this.isPatronage ? this.stripe.redirectToCheckout({
//
// Patronage.
//
items: [
{plan: 'plan_FSsO2vwva5oEOP', quantity: this.donationAmount}
],
successUrl: `${host}/patronage/?id={CHECKOUT_SESSION_ID}`,
cancelUrl: `${host}/fund-us/cancel`,
}) : this.stripe.redirectToCheckout({
//
// Donation.
//
items: [
{sku: 'sku_FVm0elVvrMW0sX', quantity: this.donationAmount}
],
successUrl: `${host}/fund-us/thank-you`,
cancelUrl: `${host}/fund-us/cancel`,
const paymentResult = await this.payment.redirectToCheckout({
isPatronage: this.isPatronage,
amount: this.donationAmount
})
const stripeResult = await stripeRedirect
if (stripeResult.error) {
if (paymentResult.error) {
showError(result.error.message)
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment