Payment components let you build the checkout into your own page while keeping card data out of your reach: the shift4.js library renders the sensitive inputs (card number, expiry, CVC) and the wallet buttons (Apple Pay, Google Pay) as Shift4-hosted components mounted inside your layout. You control the page, the styling around the fields, and when the payment is submitted; Shift4 handles the card data, payment method logic, and PCI scope.
Everything is driven by a Checkout Session created on your backend — its clientSecret is what authorizes the components in the browser.
Payment components require a fixed line-item amount (product.amount.total). Customer-chosen amounts (options/custom) aren't supported in the embedded flow yet — use Hosted checkout for those.
Load the library from Shift4:
<script src="https://js.shift4.com/v1/shift4.js"></script>| Name | URL |
|---|---|
| shift4.js script | https://js.shift4.com/v1/shift4.js |
| API base URL | https://api.shift4.com |
Initialise the library with your Platform Public Key:
var shift4 = Shift4('pk_sandbox_XXXXXXXXXXXXXXXXXXXX');The Platform Public Key (pk_…) is designed for the browser. The AccessToken you use server-side is not — never put your AccessToken in client-side code. Sandbox keys are prefixed pk_sandbox_.
If your page uses a Content Security Policy, allow the following so the library, its components, and its telemetry can load:
script-src https://js.shift4.com
frame-src https://js.shift4.com
img-src https://t.dev.shift4.com data:
connect-src https://t.dev.shift4.comEach wallet adds one or two entries on top of this baseline — see Apple Pay and Google Pay.
On your backend, create a Checkout Session and pass result[0].checkoutSession.clientSecret to the browser. Then create the checkout object:
var checkout = await shift4.createCheckout('{{clientSecret}}');The clientSecret is single-use — create a new Checkout Session for each payment attempt.
Create components from the checkout object and mount them into your own elements:
checkout.createComponent('number').mount('#number');| Component | Renders |
|---|---|
number, expiry, cvc | Individual card fields — one component per input, arranged however your layout needs. |
card | A single combined card field, if you'd rather mount one component. |
apple-pay-button | The Apple Pay button — see Apple Pay. |
google-pay-button | The Google Pay button — see Google Pay. |
Wallet buttons and card fields represent separate payment flows with independent Checkout Sessions — each needs its own createCheckout() call. See Offer wallets alongside cards.