{
    "componentChunkName": "component---src-templates-article-page-template-js",
    "path": "/how-to/enable-payment-intents/",
    "result": {"data":{"markdownRemark":{"frontmatter":{"title":"Enable PaymentIntents","slug":"enable-payment-intents","updated":"2020-08-11T00:00:00.000Z","category":"how-to-payments","ingress":"Overview of how Stripe PaymentIntents work in FTW, and how you can change older FTW version to support for Strong Customer Authentication (SCA).","skills":null},"htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This guide walks you through the process of taking\n"},{"type":"element","tagName":"a","properties":{"href":"https://stripe.com/docs/payments/payment-intents","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"PaymentIntents"}]},{"type":"text","value":" into\nuse. This article covers how PaymentIntents can be used with card\npayments. On general level, the steps are the same for other payment\nmethods. See\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/concepts/payment-methods-overview/"},"children":[{"type":"text","value":"background article on payment methods"}]},{"type":"text","value":"\nand "},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/concepts/payment-intents/"},"children":[{"type":"text","value":"payment intents"}]},{"type":"text","value":" for more information.\nStripe's PaymentIntent is a new way to handle Strong Customer\nAuthentication (SCA) by using frictionless\n"},{"type":"element","tagName":"a","properties":{"href":"https://stripe.com/gb/guides/3d-secure-2","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"3D Secure 2"}]},{"type":"text","value":" authentication."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Before starting to read this article, you probably want to get familiar\nwith\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/concepts/strong-customer-authentication/"},"children":[{"type":"text","value":"Strong Customer Authentication"}]},{"type":"text","value":"\nand "},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/concepts/payment-intents/"},"children":[{"type":"text","value":"how PaymentIntent flow works"}]},{"type":"text","value":" by\nreading related background articles."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note: Taking Stripe PaymentIntent flow into use, is a big change for\nCheckoutPage and includes process change. You should carefully check\nwhat kind of changes are made in FTW release:\n"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/sharetribe/flex-template-web/releases/tag/v3.0.0","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"v3.0.0"}]},{"type":"text","value":".\nTaking update from upstream or even cherry-picking commits might make\nthe update easier, but you should first track your custom-code to\naffected components."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"1-process-change","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#1-process-change","ariaLabel":"1 process change permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"1. Process change"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Stripe's Payment Intents API is a new way to build dynamic payment\nflows. Its\n"},{"type":"element","tagName":"a","properties":{"href":"https://stripe.com/docs/payments/payment-intents/quickstart#automatic-confirmation-flow","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"automatic confirmation flow"}]},{"type":"text","value":"\nhelps a lot since all the authentication actions for a customer are\nincluded in a single call: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":". When called,\nStripe's SDK checks if there's a need for Strong Customer Authentication\n(SCA) and creates a popup to card issuer's website."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"However, to be able to call "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"confirmCardPayment"}]},{"type":"text","value":", there needs to be a\nnew state to the transaction process. Because of this, we have split the\nprevious transition (Initial - request -> Preauthorized) into two:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 635px; "},"children":[{"type":"text","value":"\n      "},{"type":"element","tagName":"a","properties":{"className":["gatsby-resp-image-link"],"href":"/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/983a9/paymentintent-process-change.png","style":"display: block","target":"_blank","rel":["noopener"]},"children":[{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 53.459119496855344%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB2klEQVQoz2VT2XLaQBDk/78nD3ElJmUw2JBg7iM4scsgoZXQrq49tBDRqR0OXw9dI83u9HRPzdZSaZAU+g0MPuf0JXeOuSqRa/sO7qzmDlVpIXVJMZcacVqgOP1LU0Ia+4nUCzleNiFWQYTVxiGkOiKsDgcYo3GoKoo+i2CtRVVV2O/3+FdVECei1ClWJTrDCb79aOL7TQv1xh2adz/hsRg1uiQNYp4gYhuwOEWUFESw5QLhln+yL5RBdzRDvdFGo91Fq9NDbzCGF54IXTHjKZExFiAMNqSEC4E45sjcvFR5iam2uB+McXXdwG2nh9v7X+g+DOFH/GjZkWbKHAvMDkJwyDyDNiW01jTHFYvhhxzrIMJGZGj3R/jy9RpX9SZuWh1S6bHtUeHFSq4QiRxeKKiJSDNwkRxHkhaIU0lxmyv050uyOZkvMZouMBjPjoRnhYXZEdnTOgCLEyTSIGAR/ICB55rUkxPXSBpM/zxjOl9iungkTGa/X2doSossLyCVgi53VFju9mRXKQW727/uo3MiDQaLR/SHE1Lm8DCcYB2cLOvS0rwcsds/kWsoY095S02SN2vj4rPP8PfFw9PKJ7jvkGdHy5el/fAaEmneLfP5jiP9+Eoc3Dj+AxKWOyDsjjQuAAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n  "},{"type":"element","tagName":"picture","properties":{},"children":[{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/82e29/paymentintent-process-change.webp 159w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/ef33f/paymentintent-process-change.webp 318w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/f1837/paymentintent-process-change.webp 635w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/29549/paymentintent-process-change.webp 953w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/d9b8e/paymentintent-process-change.webp 1194w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/webp"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/8b9b5/paymentintent-process-change.png 159w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/fa108/paymentintent-process-change.png 318w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/53fb6/paymentintent-process-change.png 635w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/5a426/paymentintent-process-change.png 953w","/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/983a9/paymentintent-process-change.png 1194w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/png"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"src":"/docs/legacy/static/f210d23ed00ac77c58b523a81544f39a/53fb6/paymentintent-process-change.png","alt":"PaymentIntents flow needs a process change","title":"PaymentIntents flow needs a process change","loading":"lazy","decoding":"async","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"},"children":[]},{"type":"text","value":"\n        "}]},{"type":"text","value":"\n  "}]},{"type":"text","value":"\n    "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"So, after transitions ("},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment"}]},{"type":"text","value":" or\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment-after-enquiry"}]},{"type":"text","value":"), API returns\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripePaymentIntentClientSecret"}]},{"type":"text","value":" among the protected data of the\ncurrent transaction. This client-secret is used for the call to\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":". Then there is another transition made\nagainst Marketplace API, so that it can confirm the PaymentIntent and\npreauthorize the order. Transaction process continues normally after\nthat - i.e. Provider has to accept or reject the order."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Concrete steps here are changing the transaction process, then updating\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"bookingProcessAlias"}]},{"type":"text","value":" in "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"config.js"}]},{"type":"text","value":" and making necessary changes to\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"src/util/transaction.js"}]},{"type":"text","value":" file. Remember, when transaction process is\nchanged, you need to go through all the files that import transitions or\nutility functions from "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"util/transaction"}]},{"type":"text","value":". In practice, we made changes\nto "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"InboxPage"}]},{"type":"text","value":", "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"TransactionPage"}]},{"type":"text","value":", "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"TransactionPanel"}]},{"type":"text","value":", "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"ActivityFeed"}]},{"type":"text","value":",\n"},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"BookingBreakdown"}]},{"type":"text","value":", "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"BookingDatesForm"}]},{"type":"text","value":", and "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"CheckoutPage"}]},{"type":"text","value":". The list\nmight be different if you have customized your components or process."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The default transaction process supports SCA, but if you have an older\nprocess version without PaymentIntents, you can see our new example\nprocesses here:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://github.com/sharetribe/example-processes","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"https://github.com/sharetribe/example-processes"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"All the example processes support SCA. If you need help with the\nconcrete steps to customize your process to support SCA, contact Flex\nsupport from the support widget in Console and we'll guide you through\nthe changes."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"2-add-new-thunk-calls-to-stripeduckjs","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#2-add-new-thunk-calls-to-stripeduckjs","ariaLabel":"2 add new thunk calls to stripeduckjs permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"2. Add new thunk calls to stripe.duck.js"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"When using PaymentIntent flow, we don't need "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.createToken"}]},{"type":"text","value":"\nanymore, but we need to add two new thunk calls:\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.retrievePaymentIntent"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" is needed to provide SCA as mentioned\nearlier. However, since customers are making several AJAX calls on\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"CheckoutPage"}]},{"type":"text","value":", it is possible that there is a network error or\nsomething else happening between those calls. Even the whole page, might\nbe reloaded at some point. We need to retrieve up-to-date PaymentIntent\nfrom Stripe API and check its status to be able to continue the payment\nprocess. This can be done with "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.retrievePaymentIntent"}]},{"type":"text","value":"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note: previously "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" was called\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.handleCardPayment"}]},{"type":"text","value":" which is now deprecated. Basically,\nhandleCardPayment has been renamed to confirmCardPayment. In addition\nto the rename, Stripe has slightly modified the arguments. These\nchanges should not affect the behavior of the method."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"3-checkoutpage-add-new-api-calls-and-call-them-in-sequence","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#3-checkoutpage-add-new-api-calls-and-call-them-in-sequence","ariaLabel":"3 checkoutpage add new api calls and call them in sequence permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"3. CheckoutPage: add new API calls and call them in sequence"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The biggest change happens in CheckoutPage. When a user submits\nStripePaymentForm and "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"handleSubmit"}]},{"type":"text","value":" is called from CheckoutPage, new\ndata needs to be prepared (billing details: name, email, and billing\naddress) and then 4 thunk-calls/Promises need to be made in sequence:"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"step-1-oninitiateorder","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#step-1-oninitiateorder","ariaLabel":"step 1 oninitiateorder permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Step 1. "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"onInitiateOrder"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This tells Marketplace API to create booking and PaymentIntent\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Booking is created, so availability management blocks dates for\nconflicting bookings"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"API returns "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripePaymentIntentClientSecret"}]},{"type":"text","value":" inside transaction's\nprotectedData"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This combines both transitions:\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sdk.transitions.initate"}]},{"type":"text","value":" aka "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sdk.transitions.transition"}]},{"type":"text","value":" aka continue enquiry with\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment-after-enquiry"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Automatic expiration happens in 15 minutes, if process is not\ntransitioned to "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"'transition/confirm-payment'"}]},{"type":"text","value":" before that."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"Created transaction is saved to session storage or existing enquiry tx\nis updated. (There is more about this step later.)"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"step-2-onconfirmcardpayment","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#step-2-onconfirmcardpayment","ariaLabel":"step 2 onconfirmcardpayment permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Step 2. "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"onConfirmCardPayment"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This is a call "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If the customer must perform additional steps to complete the payment,\nsuch as authentication, Stripe.js walks them through that process."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"step-3-onconfirmpayment","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#step-3-onconfirmpayment","ariaLabel":"step 3 onconfirmpayment permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Step 3. "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"onConfirmPayment"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"This tells Marketplace API that customer has completed the payment\nrequirements. API will validate and mark the payment confirmed in\nFlex."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"step-4-onsendmessage","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#step-4-onsendmessage","ariaLabel":"step 4 onsendmessage permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"Step 4. "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"onSendMessage"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"If the customer has added an initial message to the provider, the app\nsends that message after the payment is confirmed."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 635px; "},"children":[{"type":"text","value":"\n      "},{"type":"element","tagName":"a","properties":{"className":["gatsby-resp-image-link"],"href":"/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/9395f/stripe-paymentintents-authentication-modal.png","style":"display: block","target":"_blank","rel":["noopener"]},"children":[{"type":"text","value":"\n    "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 89.937106918239%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsTAAALEwEAmpwYAAADOklEQVQ4y42Uy28bVRjF/RewZAc7FkWwQaAiWKAqUhekUUB9bIhEaReFFOrYnvucOzOuVLpoK1FFURPZErRIpJXCoyBR1OLACv4HUJPWdguoiZPGacjDrn7oTmwHQ4sY6ejeGc0995zvO/dmrLVYY4miiDiOtxHFO/MOosgRF08ij7xBdvA5RvfuYnTfbt7Z+yJHhwfY89LzvPLMk2S0MQRBkMJYi3OOKI7ScQchcRwRJ0XU8cMcP7SHY8OvcuD1AQYHXmPw5WfZvetpXnjqCTKeRGqFNAqhFToMCZ1AnP6C3PhdcuM3yY7PkZ24RfbCPGOlGkdOfcfBN4d4+9Awb+0fZGT/PkYODjFyYIhMV4W3nCQJcVwkcQJ97kfGymAvtTh55SHuchtzucWJaXh3ch6pVKr41Ien+5DRWiOEQCvVqaMnlKgzFcTHYC+uoS6tE06vU5z5k4+uP+T8V3Pp/8aYdE26rjNmlFbkgzzaaqIkIoxjnCsgzlTQF2H863Vmftri519aVBfatIE79TphGKbOfMO2nW03L5MrBIx+cIJsvsBYQSCMQ1lBEH1L7Xce+VSrNaSUeHfddPj3VKHUhryU5KUiLyTShmQLAVe/+Z7NjTZLjfssLq6w2Fjh3sJySlir1QhD26u9J1S+pl6hr4MxugefN6Uks7MVGkurzM3fpVr9g/qde9y6/RuNRpPb1WqviV27vgQpoe9WIAU2coRRhA4t2XyOG5UKm1tt7q80aa4+YKW5ytJyk7X1zVThdtijfx2AjLc5FkiEdSkKUnH02Htcu+4Jobm6xeqDdoqNjXZquV6v73S3Q9xFRipNIBTKWEIX46IEIQUzX85y9domn15Z5LPPl/lkusGvN9c7Newn7FOYCwQ5qXoKVRjxfq7AjcoPqcKFxQ0aS1usrbVotbYV1ur/Qah8sH0Nfddil8LPz547S6lcZnJqiguTU5RKJcpljzITExOPJzTWIJREWU0YOawL01F3vkstEUqkmevCJ2PnFuonzaQ7OUcSJ33XV9I5AR7FpNibd2PyeMtKpSn3u/5z9y7M3wL8KJI+Qn91CaMwzqJDg3YWE4UY10EUkrMK9z8J/wId7L7F/aC+fQAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n  "},{"type":"element","tagName":"picture","properties":{},"children":[{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/82e29/stripe-paymentintents-authentication-modal.webp 159w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/ef33f/stripe-paymentintents-authentication-modal.webp 318w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/f1837/stripe-paymentintents-authentication-modal.webp 635w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/29549/stripe-paymentintents-authentication-modal.webp 953w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/e2399/stripe-paymentintents-authentication-modal.webp 1090w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/webp"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"source","properties":{"srcSet":["/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/8b9b5/stripe-paymentintents-authentication-modal.png 159w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/fa108/stripe-paymentintents-authentication-modal.png 318w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/53fb6/stripe-paymentintents-authentication-modal.png 635w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/5a426/stripe-paymentintents-authentication-modal.png 953w","/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/9395f/stripe-paymentintents-authentication-modal.png 1090w"],"sizes":"(max-width: 635px) 100vw, 635px","type":"image/png"},"children":[]},{"type":"text","value":"\n          "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"src":"/docs/legacy/static/2594527bfeae2ec8f8db9ddda098030d/53fb6/stripe-paymentintents-authentication-modal.png","alt":"Stripe.js: PaymentIntents authentication modal","title":"Stripe.js: PaymentIntents authentication modal","loading":"lazy","decoding":"async","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;"},"children":[]},{"type":"text","value":"\n        "}]},{"type":"text","value":"\n  "}]},{"type":"text","value":"\n    "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note: "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" needs an instance of Stripe to be\npassed from StripePaymentForm. "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" will check\ncard details from connected Stripe Elements input."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"4-checkoutpage-save-updated-transaction","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#4-checkoutpage-save-updated-transaction","ariaLabel":"4 checkoutpage save updated transaction permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"4. CheckoutPage: save updated transaction"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"We use session storage to buffer checkout page against page reloads and\nerrors - customer needs to be able to continue payment after accidental\npage refresh and network errors. This is a UX issue, but more\nimportantly, it builds trust. Because of this need, we save booking\ndates and other data there. Previously enquiredTransaction was saved\nthere too, but that concept is now expanded a bit: any transaction can\nnow be saved to session storage under the key \"transaction\"."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"So, if there is an existing transaction in enquiry state and customer\nbooks the listing, TransactionPage sends that "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"transaction"}]},{"type":"text","value":" to\nCheckoutPage. As a first step CheckoutPage saves received data to the\nsession store. This is pretty much the same functionality as with\nprevious card-token payment process - only the key is changed from\n"},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"enquiryTransaction"}]},{"type":"text","value":" to "},{"type":"element","tagName":"em","properties":{},"children":[{"type":"text","value":"transaction"}]},{"type":"text","value":". However, after transition\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment"}]},{"type":"text","value":" (or "},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"request-payment-after-enquiry"}]},{"type":"text","value":") the updated\ntransaction is saved again. (the relevant new data in transaction is\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripePaymentIntentClientSecret"}]},{"type":"text","value":".)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"In addition, the handling of booking breakdown with\nSpeculatedTransaction needs to be changed because saved transaction\nalready contains booking in some cases and a new call to\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"sdk.transactions.initiateSpeculative"}]},{"type":"text","value":" would just return a conflict\nerror telling about an already existing booking."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"5-stripepaymentform-adding-billing-details-and-showing-errors","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#5-stripepaymentform-adding-billing-details-and-showing-errors","ariaLabel":"5 stripepaymentform adding billing details and showing errors permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"5. StripePaymentForm: adding billing details and showing errors"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Most of the visual changes happen in StripePaymentForm. Billing details\nare added to the form and most of the errors of different thunk calls\nare shown inside it."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"The default mode for FTW is to show billing address fields. Even though\nit is recommended by Stripe, you might want to remove those fields due\nto UX reasons. That can be made just by not adding\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"StripePaymentAddress"}]},{"type":"text","value":" sub-component."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Note: if the page is reloaded after successful call to\n"},{"type":"element","tagName":"code","properties":{},"children":[{"type":"text","value":"stripe.confirmCardPayment"}]},{"type":"text","value":" billing details should not be shown to the\nuser since credit card number and other billing details are already\nsent to Stripe."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"6-test-with-live-credit-cards","style":"position:relative;"},"children":[{"type":"element","tagName":"a","properties":{"href":"#6-test-with-live-credit-cards","ariaLabel":"6 test with live credit cards permalink","className":["anchor","before"]},"children":[{"type":"element","tagName":"svg","properties":{"ariaHidden":"true","focusable":"false","height":"16","version":"1.1","viewBox":"0 0 16 16","width":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"},"children":[]}]}]},{"type":"text","value":"6. Test with live credit cards"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Since 3D Secure authentication flow is different between different\ncredit card issuers, you should test at least some credit cards how they\nwork in a live environment."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"This can be done by creating another\n"},{"type":"element","tagName":"a","properties":{"href":"/docs/legacy/ftw/how-to-deploy-ftw-to-production/"},"children":[{"type":"text","value":"live environment"}]},{"type":"text","value":" FTW instance\nthat uses your live Client Id for Flex with live Stripe keys (both\npublishable and secret). Then create a new Git branch that takes\nPaymentIntents flow into use and adds\n"},{"type":"element","tagName":"a","properties":{"href":"https://github.com/sharetribe/flex-template-web/blob/master/.env-template#L32","target":"_blank","rel":["noopener","noreferrer"]},"children":[{"type":"text","value":"Basic Authentication configuration"}]},{"type":"text","value":"\ninto environment variables. After that, you could deploy your\npayment-intent branch into your live environment. Then you can just book\nsome existing listing and maybe reject it to get refund to your live\ncard account."}]}],"data":{"quirksMode":false}},"headings":[{"value":"1. Process change","depth":2},{"value":"2. Add new thunk calls to stripe.duck.js","depth":2},{"value":"3. CheckoutPage: add new API calls and call them in sequence","depth":2},{"value":"Step 1. onInitiateOrder","depth":3},{"value":"Step 2. onConfirmCardPayment","depth":3},{"value":"Step 3. onConfirmPayment","depth":3},{"value":"Step 4. onSendMessage","depth":3},{"value":"4. CheckoutPage: save updated transaction","depth":2},{"value":"5. StripePaymentForm: adding billing details and showing errors","depth":2},{"value":"6. Test with live credit cards","depth":2}]}},"pageContext":{"slug":"enable-payment-intents","category":"how-to-payments"}},
    "staticQueryHashes": ["3794076007","439097193","717698143"]}