Skip to content

Instantly share code, notes, and snippets.

@heymartinadams
Last active April 19, 2018 01:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heymartinadams/3a92ed6769099b23e01d465a623dfac2 to your computer and use it in GitHub Desktop.
Save heymartinadams/3a92ed6769099b23e01d465a623dfac2 to your computer and use it in GitHub Desktop.
import React from 'react'
import StripeCheckout from 'react-stripe-checkout'
import { graphql } from 'react-apollo'
import { userQuery, signinUser } from './graphql/user'
import { createCard, receiveStripeId, createPurchase, checkIfPaid, upgradeApp } from './graphql/purchase'
class Stripe extends React.Component {
constructor(props) {
super(props)
this.state = {
buttonStyle: 'button primary',
status: 'Nothing happened yet'
}
this.onToken = this.onToken.bind(this)
this.stripeTokenSubscription = null
this.purchaseSubscription = null
}
componentWillMount() {
// First create a user via your graph.cool console, then enter username and password here for testing purposes only.
this.props.signinUser({ variables: { email: "EXAMPLE@EXAMPLE.COM", password: "XXXXXX" } }).then(({ data }) => {
console.log('Signed in.');
window.localStorage.setItem('graphcoolToken', data.signinUser.token)
})
}
componentDidUpdate(newProps) {
if (this.props.data.user) {
const userId = this.props.data.user.id
if (!this.stripeTokenSubscription && !this.purchaseSubscription) {
// Logic #5: Create subscription to trigger response once user in User model has been successfully assigned a Stripe customer ID
this.stripeTokenSubscription = newProps.data.subscribeToMore({
document: receiveStripeId,
variables: { userId },
updateQuery: (previousState, { subscriptionData }) => {
console.log('Purchasing...')
this.setState({ status: 'Purchasing...' })
// Logic #6: Now that user has a Stripe customer Id (ie. subscription has been triggered), make a purchase by creating a node in Purchase model.
this.props.createPurchase({ variables: { userId } })
.then(() => {
console.log('Purchase complete')
this.setState({ status: 'Purchase complete...' })
// Cancel current subscription
this.stripeTokenSubscription()
})
.catch((e) => { console.error(e) })
},
onError: (err) => console.error(err)
})
// Logic #9: Create subscription to trigger response once purchase in Purchase model has been successfully updated with isPaid as true.
this.purchaseSubscription = newProps.data.subscribeToMore({
document: checkIfPaid,
variables: { userId },
updateQuery: (previousState, { subscriptionData }) => {
console.log('Upgrading...')
this.setState({ status: 'Upgrading...' })
// Logic #10: Now that Stripe charge was successful and that Purchase model has been updated with isPaid as true upgrade the app
this.props.upgradeApp({ variables: { userId } })
.then(() => {
console.log('Upgrade complete!')
this.setState({ status: 'Upgrade complete!' })
// Cancel current subscription
this.purchaseSubscription()
// Implement any other logic to indicate that the user has successfully upgraded here.
})
.catch(err => console.error(err))
return null
},
onError: (err) => console.error(err)
})
}
}
}
onToken(token) {
// This is where token is received, as described in Logic #1
const userId = this.props.data.user.id
const stripeToken = token.id
// Hide or remove button to prevent duplicate purchases
this.setState({ buttonStyle: 'button hidden' })
// Logic #2
this.props.createCard({ variables: { stripeToken, userId } })
.then(() => {
console.log('Customer created...')
this.setState({ status: 'Customer created...' })
})
.catch((e) => { console.error(e) })
}
render() {
if (this.props.data.loading) {
return (<div>Loading...</div>)
}
const { buttonStyle, status } = this.state
return (
<div>
<StripeCheckout
name="PRODUCT TITLE"
description="PRODUCT DESCRIPTION"
image="https://PATH_TO_IMAGE_HERE.png"
ComponentClass="div"
panelLabel="Upgrade"
amount={999}
currency="USD"
// Replace with your Stripe test publishable key: pk_test_xxxxxxxxxxxxxxxxxxxxxxxx
stripeKey="pk_test_xxxxxxxxxxxxxxxxxxxxxxxx"
email={this.props.data.user.email}
shippingAddress={false}
billingAddress={true}
zipCode={true}
bitcoin
allowRememberMe
token={this.onToken}
reconfigureOnUpdate={false}
triggerEvent="onClick"
>
<div className={buttonStyle}>Upgrade</div>
</StripeCheckout>
<br />
<center>{status}</center>
</div>
)
}
}
Stripe.propTypes = {
createCard: React.PropTypes.func.isRequired,
createPurchase: React.PropTypes.func.isRequired,
upgradeApp: React.PropTypes.func.isRequired,
data: React.PropTypes.object.isRequired
}
export default
graphql(signinUser, { name: 'signinUser' })(
graphql(createCard, { name: 'createCard' })(
graphql(createPurchase, { name: 'createPurchase' })(
graphql(upgradeApp, { name: 'upgradeApp' })(
graphql(userQuery)(Stripe)
)
)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment