Skip to content

Instantly share code, notes, and snippets.

@njbotkin
Created August 31, 2019 21:34
Show Gist options
  • Save njbotkin/d3f7201ef3caaaa543a4264200f7f329 to your computer and use it in GitHub Desktop.
Save njbotkin/d3f7201ef3caaaa543a4264200f7f329 to your computer and use it in GitHub Desktop.
Synchronous Stripe PaymentIntents Flow
export async function api(method, path = '', { body = {}, headers = {} } = {}) {
/* global ORIGIN */
let opts = { method, headers }
if(method == 'POST') {
opts.body = JSON.stringify(body)
}
let res = await fetch((process.browser ? '' : ORIGIN) + '/api/'+path, opts)
res.text = await res.text()
try {
res.json = JSON.parse(res.text)
} catch(e) {
res.json = {}
}
if(res.json.errors) {
res.errors = res.json.errors
} else if(!res.ok) {
res.errors = [{ message: res.text }]
} else {
res.errors = []
}
return res
}
async function pay() {
let payment_method = await stripe.createPaymentMethod('card', card, {
billing_details: billing
})
if (payment_method.error) {
errs = [payment_method.error]
spinning = false
} else {
// step 2
handleServerResponse(await api('POST', 'pay', { body: {
payment_method_id: payment_method.paymentMethod.id
} }))
}
}
async function handleServerResponse(response) {
let { json, status, text, errors } = response
if(errors.length) {
errs = errors
}
else if (json.requires_action) {
// step 3
let action = await stripe.handleCardAction(json.payment_intent_client_secret)
if (action.error) {
errs = [action.error]
} else {
handleServerResponse(await api('POST', 'pay', { body: {
payment_intent_id: json.paymentIntent.id
} }))
}
} else {
dispatch('success')
}
}
// assume an express-like context with req, res, etc
let send = require('@polka/send-type')
if (req.body.payment_method_id) {
intent = await stripe.paymentIntents.create({
payment_method: req.body.payment_method_id,
amount: rate.total,
currency: 'usd',
confirmation_method: 'manual',
confirm: true
})
} else if (req.body.payment_intent_id) {
intent = await stripe.paymentIntents.confirm(req.body.payment_intent_id)
} else {
throw('Please provide stripe payment method or intent')
}
if (intent.status === 'requires_action' && intent.next_action.type === 'use_stripe_sdk') {
return send(res, 200, {
requires_action: true,
payment_intent_client_secret: intent.client_secret
})
}
if(intent.status !== 'succeeded') {
return send(res, 500, 'Invalid PaymentIntent status')
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment