🕒 This guide takes 60 minutes to embed a credit card checkout on your app.
CheckoutWithCard embeds a form on your app that accepts credit/debit card, Apple Pay, and Google Pay.
This component also handles:
- Apple Pay and Google Pay options, if supported
- Bot and anti-fraud detection
- 3D Secure prompted by the issuing bank, if necessary
- KYC of the buyer, if necessary
Example

This SDK is available in ReactJS and JavaScript.
Integration: ReactJS
- Install the ReactJS SDK:
npm install @paperxyz/react-client-sdk
yarn add @paperxyz/react-client-sdk
- Copy your API key from Developer Dashboard: Developers and contract ID from Developer Dashboard: Contracts.
- To begin a buyer session, create an SDK Client Secret via a backend API call. You'll provide some buyer info and configure checkout behavior.
- On your frontend, render the
CheckoutWithCard
component with this SDK client secret.
Example code
Backend
const resp = await fetch("https://withpaper.com/api/2022-08-12/checkout-sdk-intent", {
method: "POST",
headers: { "Authorization": "Bearer MY_API_KEY" },
body: JSON.stringify({
contractId: "MY_CONTRACT_ID",
walletAddress: "0x...",
}),
}
if (resp.ok) {
const { sdkClientSecret } = await resp.json();
// Pass this sdkClientSecret to your frontend 👇
}
Frontend
import { CheckoutWithCard } from "@paperxyz/react-client-sdk";
<CheckoutWithCard
sdkClientSecret="MY_SDK_CLIENT_SECRET"
onPaymentSuccess={(result) => {
console.log("Payment successful.");
}}
/>
CheckoutWithCard
props
CheckoutWithCard
propsName | Type | Description |
---|---|---|
sdkClientSecret * | string | The SDK Client Secret returned from the Create Checkout Elements Client Secret API. |
onPaymentSuccess * | ({ id: string; }) => void | This method is called after the payment has been submitted for processing. This payment may still be rejected by the cardholder's bank. |
onError | (PaperSDKError) => void | This method is called when an error is encountered. |
onPriceUpdate | ({ quantity: number; unitPrice: PriceDetail; networkFees: PriceDetail; serviceFees: PriceDetail; total: PriceDetail; }) => void Where PriceDetail is { display: string; valueInSubunits: number; currency: string; } | This method is called when the price is updated or loaded for the first time. This summary is helpful to show a granular price breakdown. |
locale | enum Valid values: en , fr , es , it , de , ja , ko , zh | The language to show text in. Defaults to en . |
options | object | Customize component styling. See Customization. |
Integration: JavaScript
- Install the JavaScript SDK with your preferred package manager.
npm install @paperxyz/js-client-sdk
yarn add @paperxyz/js-client-sdk
- Copy your API key from the Developer Dashboard: Developers page.
- When a buyer wants to make a purchase, create a Checkout Elements Client Secret (API reference) to generate an SDK Client Secret. You will provide some buyer information and configure behavior via this API.
- Call
createCheckoutWithCardElement
to insert the iframe on your page. Pass the SDK Client Secret to this component.- If you don't provide
elementOrId
, this call returns an iframe element for you to insert into your page.
- If you don't provide
Example code
import { createCheckoutWithCardElement } from "@paperxyz/js-client-sdk";
// Assume a container exists:
//
// <div id="paper-checkout-container" width="380px" />
//
createCheckoutWithCardElement({
sdkClientSecret: "MY_SDK_CLIENT_SECRET",
elementOrId: "paper-checkout-container",
appName: "My Web3 App",
options,
onError(error) {
console.error("Payment error:", error);
},
onPaymentSuccess({ id }) {
console.log("Payment successful.");
},
});
// Alternatively, insert the iframe programmatically:
//
// const iframe = createCheckoutWithCardElement(...)
// document.getElementById('paper-checkout-container').appendChild(iframe);
Props
Name | Type | Description |
---|---|---|
sdkClientSecret * | string | The client secret returned from the Checkout SDK intent API. |
elementOrId | string | HTMLElement | If provided, the iframe will be appended this element. You can pass in the DOM element or the id associated with the element.A minimum width of 380px is recommended. |
appName | string | If provided, the wallet card will display your appName . |
locale | enum Valid values: en , fr , es , it , de , ja , ko , zh | The language to show text in. Defaults to en . |
option | object | Customize component styling. See Customization. |
onLoad | () => void | This method is called when the iframe loads. |
onError | (error: PaperSDKError) => void | This method is called when an error occurs during the payment process. |
onPaymentSuccess | (props : { id: string }) => void | This method is called when the buyer has successfully paid. |
onReview | (props: { cardholderName: string, id: string }) => void | This method is called after the user enters their card details. |
Customization
The optional options
argument allows you to customize the component's styling. All customization fields are optional.
options
object
options
objectName | Type | Description |
---|---|---|
colorPrimary | string In hex, e.g. #cf3781 | The primary brand color for buttons and links. |
colorBackground | string In hex, e.g. #cf3781 | The background color of the page. |
colorText | string In hex, e.g. #cf3781 | The color for text on the page and UI elements. |
borderRadius | number In px, e.g. 0 for sharp corners, 12 for rounded corners, 24 for pill shape | The roundness of buttons and input elements. |
inputBorderColor | string In hex, e.g. #cf3781 | The border color of the input field. |
inputBackgroundColor | string In hex, e.g. #cf3781 | The background color of the input field. |
Examples
Here's an example component with the following props:
{
colorBackground: '#fefae0',
colorPrimary: '#606c38',
colorText: '#283618',
borderRadius: 6,
inputBackgroundColor: '#faedcd',
inputBorderColor: '#d4a373',
}
FAQ
How do I prevent the 3D Secure or KYC modal from popping up behind my other frontend components?
The SDK uses a z-index of 10000
for these modals. If they are appearing behind other components, please lower your component's z-index values.