handle-stripe-payment-action.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { FetchError, postJSON } from '@/infrastructure/fetch-json'
  2. import getMeta from '@/utils/meta'
  3. import { loadStripe } from '@stripe/stripe-js/pure'
  4. export default async function handleStripePaymentAction(
  5. error: FetchError
  6. ): Promise<{ handled: boolean }> {
  7. const clientSecret = error?.data?.clientSecret
  8. const publicKey = error?.data?.publicKey
  9. if (clientSecret && publicKey) {
  10. const stripe = await loadStripe(publicKey)
  11. if (stripe) {
  12. const currentPath = window.location.pathname
  13. const returnUrl = new URL(
  14. '/user/subscription/offsite',
  15. getMeta('ol-ExposedSettings').siteUrl
  16. )
  17. const returnParams = new URLSearchParams({
  18. path: currentPath,
  19. })
  20. returnUrl.search = returnParams.toString()
  21. const manualConfirmationFlow = await stripe.confirmPayment({
  22. clientSecret,
  23. redirect: 'if_required',
  24. confirmParams: {
  25. return_url: returnUrl.toString(),
  26. },
  27. })
  28. if (manualConfirmationFlow.error) {
  29. const paymentIntentId = manualConfirmationFlow.error.payment_intent?.id
  30. try {
  31. await postJSON(
  32. `/user/subscription/void-change?payment_intent_id=${paymentIntentId}`
  33. )
  34. } catch (error) {
  35. // do nothing
  36. }
  37. return { handled: false }
  38. } else {
  39. try {
  40. await postJSON(`/user/subscription/sync`)
  41. } catch (error) {
  42. // if the sync fails, there may be stale data until the webhook is
  43. // processed but we can't do any special handling for that in here
  44. }
  45. return { handled: true }
  46. }
  47. }
  48. }
  49. return { handled: false }
  50. }