Created
August 31, 2019 21:34
-
-
Save njbotkin/d3f7201ef3caaaa543a4264200f7f329 to your computer and use it in GitHub Desktop.
Synchronous Stripe PaymentIntents Flow
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 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') | |
} | |
} |
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
// 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