Pick the integration
Install
Install the NPM package and, optionally, the TypeScript definitions:loadScript injects the SDK script and resolves with the Yuno object. Initializing is a second step: call Yuno.initialize with your public API key to get the instance you mount with. Set sri: true so the browser verifies the script against its published hash (see Subresource Integrity).
If your account is in the EU region, pass
region: 'eu' to loadScript as well.Yuno.initialize from the browser:
Create the checkout session on your server
The SDK needs a checkout session, and creating one requires your private key. Create it on your server and pass the id to the component as a prop. The session expires after 2.5 hours in production, so create it when the shopper reaches the payment step, not at page build time.Load the SDK once
A small hook keeps one SDK instance per page and shares it between components. The promise is cached at module level so React StrictMode, which runs effects twice in development, does not inject the script twice.Seamless SDK in a component
Mount insideuseEffect, keep the callbacks in a ref so a re-render does not remount the form, and call unmountSdk in the cleanup. elementSelector is the element the checkout mounts into and is required. Use renderMode.type: 'element' so the payment method and action forms also render inside elements you own.
The Seamless SDK creates the payment itself from the checkout session, so there is no yunoCreatePayment callback and no Create Payment call from your server. It also runs the payment retry for declined cards on its own. You get the outcome in yunoPaymentResult, and your server gets it from the payment.purchase webhook.
- Dependencies: only
yuno,checkoutSession, andcountryCoderemount the form. Callbacks go through a ref so parent re-renders do not tear the checkout down. - Cleanup:
unmountSdkremoves the SDK from the DOM. If the component unmounts whilemountSeamlessCheckoutis still running, thecancelledcheck unmounts it as soon as it finishes, so no form is left behind in a detached element. - Opening the form:
startPaymentopens the selected payment method. Call it from your pay button as shown, or right aftermountSeamlessCheckoutresolves. If you never call it, the form does not open.
Lite SDK in a component
Lite SDK renders one payment method per call. The React pattern is the same, withstartCheckout and mountCheckoutLite instead of the Seamless methods. Express buttons mount separately with mountExternalButtons.
Unlike Seamless, Lite hands you a one-time token in yunoCreatePayment and your server creates the payment. Your /api/payments route calls Create Payment with payment_method.token and checkout.session, and the callback then follows the payment retry rules: continuePayment for a declined card or when sdk_action_required is true, unmountSdk otherwise.
Secure Fields in a form you own
Secure Fields gives you three PCI-safe inputs (pan, expiration, cvv) that render into elements in your form. yuno.secureFields is asynchronous, so await it inside the effect, then create the fields and generate the one-time token on submit.
Secure Fields are not removed by unmountSdk. Keep each field and call its unmountSync in the cleanup, otherwise the card inputs stay in the page and StrictMode renders them twice in development.
continuePayment so the payment retry can keep the form open with the decline shown. Anything else that needs no further action goes to mountStatusPayment.
Set checkoutSession on secureFields({ ... }) and not on generateTokenWithInformation; the payment retry logic depends on it.
Next.js
App Router
Components underapp/ are server components by default. Put every SDK call in a file that starts with 'use client', and create the session in a server action or route handler.
next/dynamic and ssr: false:
Pages Router
Create the session ingetServerSideProps and render the client component. The useEffect hook only runs in the browser, so the component above works unchanged.
Environment variables
The private secret key must never be prefixed with
NEXT_PUBLIC_.
Reduce layout shift
The checkout loads after the page renders. Reserve the space it will take so the page does not jump:- Give the mount element a
min-heightclose to the final form height. - Keep
showLoading: true(the default) so the SDK shows its own spinner while it fetches your payment methods. - Call
loadScripton the page before the payment step if you can, so the script is already cached when the shopper arrives. It loads the same file on every page, so the browser downloads it once.
Troubleshooting
Next steps
Migrate from Stripe Elements
Map every Elements concept to its Yuno equivalent.
Web Reference
Every parameter, callback, and lifecycle method of the Web SDK.