๐จโ๐ป React components for the Mojito Platform, Reference App and third-party projects, including Mojito's Checkout / Payment UI and payment sandbox / test app to easily test credit card, ACH, Wire and Crypto payments with Circle, 3DS, Plaid, Vertex and TaxJar integrations.
๐ Check it out at https://payments-staging.mojito.xyz/!
Mixer v1 to Mixer v2 Migration
You can install this project with one of these commands:
npm install --save @mojito-inc/mixers
yarn add @mojito-inc/mixers
Alternatively, once you've built the library using yarn build
, you can install it locally in another project adding
this line to your package.json
's dependencies. If you update it, make sure you remove the entry from yarn.lock
and
re-install it.
"@mojito-inc/mixers": "file:../mojito-mixers"
Also, make sure you install the following dependencies:
react
react-dom
@mui/material
And also, keep in mind:
-
@emotion/react
is not needed. -
@emotion/styled
is needed as stated in MUI's docs:Keep
@emotion/styled
as a dependency of your project. Even if you never use it explicitly, it's a peer dependency of@mui/material
. -
styled-components
is needed as stated inreact-payment-inputs
' docs, but it's not used:Note: requires styled-components to be installed as a dependency.
By default, React Payment Inputs does not have built-in styling for it's inputs. However, React Payment Inputs comes with a styled wrapper which combines the card number, expiry & CVC fields...
Fist, you need to create a CheckoutComponent: React.FC<PUICheckoutProps>
component that renders MojitoCheckout
and passes it all required props. Simply copy the following file and adapt it to your needs:
You can find an example here: app/src/layout/CheckoutLayout.tsx.
You'll use this CheckoutComponent
component in your code instead of MojitoCheckout
just so that you don't have to
repeat properties that rarely change, like the theme DefaultThemes
In the _app.tsx
file, please add the following line: <Script src="https://cdn.checkout.com/js/framesv2.min.js" />
. if it was not added, credit card payments won't work.
Add below packages as dependencies in your package.json
{
...
"dependencies": {
...
"url": "latest",
"http": "npm:http-browserify",
"https": "npm:https-browserify",
"zlib": "npm:browserify-zlib",
"http-browserify": "latest",
"https-browserify": "latest",
"browserify-zlib": "latest",
"assert": "^2.0.0",
"stream": "^0.0.2"
}
}
To ignore the sourcemap warnings, create a .env file with the following in your root directory:
GENERATE_SOURCEMAP=false
import { MojitoCheckout } from '@mojito-inc/mixers';
const theme = {
font: {
primary: 'Sneak',
secondary: 'Sneak',
},
color: {
primary: '#6663FD',
secondary: '#FFFFFF',
background: '#FAFAFC',
errorBackground: '#FEE3E5',
text: '#000000',
cardBackground: '#FFFFFF',
checkout: {
continueButtonBackground: '#6663FD',
continueButtonTextColor: '#FFFFFF',
disableButtonBackground: '#DADAE9',
},
placeholder: '#BABEC5',
costBreakdown: {
applyButtonBackground: '#DADAE9',
applyButtonTextColor: '#FFFFFF',
},
paymentConfirmation: {
awaitingPaymentBackground: '#f0ebeb',
awaitingPaymentTextColor: 'orange',
processedBackground: '#E5F9E0',
processedTextColor: '#000000',
copyIconColor: '#042439',
},
highlightedText: '#6663FD',
unHighlightedText: '#6663FB',
errorText: '',
linksText: '',
multiSigBackground: '',
multiSigBorder: '',
multiSigText: '',
},
};
const handleClickGoToMarketPlace = useCallback(async () => {
}, []);
const onEvent = (e:string)=>{
console.log("EVENT",e)
}
const paymentInstructions = (paymentId: string) => {
return (
<>
<Typography fontWeight="500" fontSize="20px" marginBottom="8px">
Thank you for your purchase! The order is on its way to you.
</Typography>
<Typography
fontSize="16px"
variant="body1"
color="#8A8AB9">
Order #: { paymentId }
</Typography>
<Typography marginTop="16px" variant="body2">
We have received your payment. Once everything is confirmed, we will send an email with your order confirmation.
<br />
<br />
If you choose to store your NFT in a wallet, you can view it on the respective wallet page.
<br />
<br />
If you selected to have it sent to an email wallet, you should find it by logging into <a href="https://ews.thirdweb.com/">https://ews.thirdweb.com/</a>.
</Typography>
</>
);
};
<MojitoCheckout
uri={ API_URL }
userInfo: {
email: user?.email,
},
checkoutOptions={{
orgId: 'd086ea16-d40d-454c-84a4-64b5e940670a',
lotId: '17cd1000-323d-4a20-8e5f-7a8598ffae2a',
quantity: 1,
collectionItemId: '64e99437-ac2e-45bc-b4a6-4750985b4e81',
discountCode: '',
invoiceId: '',
}}
theme={ theme }
events={
onEvent:onEvent,
onCatch:onCatch,
onError:onError,
}
walletDetails={{
wallet: {
account: walletAddress,
chainId: chainId,
connected: true,
balance: currencyBalance,
providerType: 'Metamask',
}, // Pass custom connected wallet details
saveWalletData: saveWalletData, // In the function callback you will get a wallet details
onDisconnect: onDisconnect, // To handle custom disconnect connect wallet
onClickRefetchBalance: onClickRefetchBalance, // To handle custom refetch balance
}}
onClickConnectWallet={ onClickConnectWallet } // To handle custom connect wallet component
uiConfiguration={
global:{
logoSrc: require('./logo.svg),
loaderImageSrc: require('./loading.svg),
errorImageSrc: require('./error.svg),
}
payment: {
creditCard: true,
walletConnect: true,
wire: true,
coinbase: true
},
costBreakdown: {
showDiscountCode: true
},
paymentConfirmation: {
onGoTo: () => handleClickGoToMarketPlace(),
creditCardInstructions: paymentInstructions //Your own instructions for credit card,
metamaskInstructions: paymentInstructions //Your own instructions for metamask,
wireTransferInstructions: paymentInstructions //Your own instructions for wire transfer,
},
delivery: {
creditCard: {
enableMultiSig: false,
apiKey: configuration.PAYMENT_API_KEY,
},
},
walletConnect: {
orgId: configuration.ORGANIZATION_ID,
walletConnectProjectId: configuration.PROJECT_ID,
paperClientId: configuration.PAPER_CLIENT_ID,
clientId: configuration.clientId,
activeChain: configuration.activeChain,
isPaperWallet: false, // if true it will work as paper wallet
isWeb2Login: false, // if true it will work as web2 login (Auth0)
skipSignature: false, // if true it will skip the signature process
theme: ConnectWalletTheme, // Custom connect wallet theme
},
walletOptions: {
enableEmail: true,
enableMetamask: true,
enableWalletConnect: true,
},
}
show={ show }
token={ token } />
Prams | Type | Required | Description |
---|---|---|---|
uri | string | โ | API url |
userInfo | object | โ | UserInfo |
show | boolean | โ | to open checkout modal |
checkoutOptions | object | โ | CheckoutOptions |
theme | object | Theme | |
events | object | Events, you will get the logs | |
onClickConnectWallet | function | Your own connect wallet logic | |
walletDetails | object | pass connected wallet details if you add own connect wallet logic else no need to pass | |
uiConfiguration | object | UIConfiguration | |
success | boolean | to show success popup | |
token | string | pass bearer token | |
debug | boolean | if true you will see the logs |
Prams | Type | Description |
---|---|---|
string | To show email in UI |
Prams | Type | Description |
---|---|---|
orgId | string | Your organization id |
lotId | string | Lot id you will get from mint portal |
quantity | number | quantity of the token |
paymentId | string | paymentId for the success popup |
collectionItemId | string | Pass item Id to get the details of an item |
discountCode | string | coupon code |
vertexEnabled | boolean | to calculate tax |
invoiceId | string | pass invoiceId for auction case |
successURL | string | success Redirect URL |
errorURL | string | error Redirect URL |
Prams | Type | Description |
---|---|---|
wallet | object | Pass connected Wallet details if you add your own wallet logic |
saveWalletData | function | In the function callback you can get the connected wallet details |
onDisconnect | number | To handle your own disconnect function |
onClickRefetchBalance | string | To handle your own re-fetch function |
Prams | Type | Description |
---|---|---|
global | object | Global config |
payment | object | Payment Config |
costBreakdown | object | Const breakdown UI config |
paymentConfirmation | object | Payment confirmation UI config |
delivery | object | Delivery UI config |
walletConnect | object | Connect Wallet SDK config |
walletOptions | object | Connect wallet options |
breadCrumbs | array | Custom breadCrumbs name |
isAutoFillCountryCode | boolean | To enable auto fill countryCode |
Prams | Type | Description |
---|---|---|
logoSrc | string | Logo url |
loaderImageSrc | string | loader url |
errorImageSrc | string | error url |
Prams | Type | Description |
---|---|---|
walletConnect | boolean | To enable wallet connect |
wire | boolean | To enable wire |
creditCard | boolean | To enable credit card |
coinbase | boolean | To enable coinbase |
Type | Description | |
---|---|---|
showDiscountCode | boolean | To hide or show discount UI |
showProductionDisclaimer | boolean | To hide or show production disclaimer UI |
productDisclaimerText | string | Custom product disclaimer text |
Type | Description | |
---|---|---|
wireTransferInstructions | JSX Element | Custom component for wire transfer instructions |
creditCardInstructions | JSX Element | Custom component for credit card instructions |
metamaskInstructions | JSX Element | Custom metamask instructions |
onGoTo | function | Function to handle back to marketplace button |
Prams | Type | Description |
---|---|---|
walletConnect | Object | MojitoDeliveryType |
wire | Object | MojitoDeliveryType |
creditCard | Object | MojitoCheckoutDeliveryType |
coinbase | Object | MojitoDeliveryType |
description | JSX Element (or) string | Description for Delivery |
Prams | Type | Description |
---|---|---|
enableMultiSig | boolean |
Prams | Type | Description |
---|---|---|
enableMultiSig | boolean | |
apiKey | string | api key for credit card payment |
Prams | Type | Description |
---|---|---|
walletConnectProjectId | boolean | Wallet connect project id |
paperClientId | boolean | Email wallet paper client id |
content | object | To customise the connect wallet modal contents |
isWeb2Login | boolean | Connect wallet by web2 login |
skipSignature | boolean | Connect wallet by skipping signature process |
theme | Theme | Customise the wallet connect theme |
clientId | string | |
activeChain | string | |
isPaperWallet | boolean |
Type | Description | |
---|---|---|
enableEmail | boolean | To hide or show Email wallet button |
enableMetamask | boolean | To hide or show metamask button |
enableWalletConnect | boolean | To hide or show wallet connect button |
import { createTheme } from '@mui/material/styles';
export const ConnectWalletTheme = createTheme({
typography: {
fontFamily: 'untitled_sansregular_regular',
},
components: {
MuiTextField: {
styleOverrides: {
root: {
'& input::-webkit-outer-spin-button, & input::-webkit-inner-spin-button':
{
display: 'none',
},
'& input[type=number]': {
MozAppearance: 'textfield',
},
},
},
},
MuiCssBaseline: {
styleOverrides: `
@font-face {
font-family: untitled_sansregular_regular;
font-style: normal;
font-display: swap;
font-weight: 400;
text-transform: none;
font-size: 16px;
color: #000;
}
`,
},
MuiButton: {
styleOverrides: {
root: {
fontFamily: 'untitled_sansregular_regular',
textTransform: 'none',
borderRadius: '4px',
fontWeight: 700,
fontSize: '16px',
border: '1px solid #242629',
backgroundColor: '#fff',
color: '#242629',
'&:hover': {
backgroundColor: '#fff',
color: '#242629',
opacity: 0.5,
},
},
},
},
MuiDialog: {
styleOverrides: {
paper: {
border: '1px solid #D7D8DB',
boxShadow: '0px 8px 16px rgba(0, 0, 0, 0.08)',
borderRadius: '4px',
},
},
},
MuiDivider: {
variants: [
{
props: { orientation: 'horizontal' },
style: {
':before': {
borderTop: 'thin solid #D7D8DB',
},
':after': {
borderTop: 'thin solid #D7D8DB',
},
},
},
],
},
},
palette: {
primary: {
main: '#242629',
},
secondary: {
main: '#A6FF00',
},
backgroundColor: {
primary: '#ffffff',
secondary: '#000000',
},
grey: {
100: '#F5F5F5',
500: '#9E9E9E',
},
toastError: {
500: '#CE2818',
},
},
});
Address Validation & Tax Calculation with Vertex or TaxJar
If you'd like address to be validated and taxes to be calculated during the checkout process, particularly in the Billing Information step, you need a Vertex or TaxJar account. Once you have it, you need to configure it in Mojito Mint.
Alternatively, set the following prop to disable those calls to the backend: vertexEnabled = false
.
<MojitoCheckout
checkoutOptions={{
orgId: 'd086ea16-d40d-454c-84a4-64b5e940670a',
lotId: '17cd1000-323d-4a20-8e5f-7a8598ffae2a',
quantity: 1,
paymentId: '<payment id>',
collectionItemId: '64e99437-ac2e-45bc-b4a6-4750985b4e81',
discountCode: 'ZZTO',
vertexEnabled: false,
}} />
We use Checkout for payments, so the supported countries depend on which payment method is going to be used, as described here:
If you quickly click the logo in the top-right corner 16 times, the debug mode will be enabled (toggled, actually), even in production and regardless of
the initial value you passed for the debug
prop.
The debug mode will, among logging/displaying some other less relevant pieces of data:
Create an error page with the page path /payments/failure
:
Create an success page with the page path /payments/success
:
The success
parameter should be passed as true to the MojitoCheckout
component.
<MojitoCheckout
userInfo={{
email: email, // pass the user email
}}
checkoutOptions={{
paymentId,
}}
show={ true }
success={ true }
uiConfiguration={{
paymentConfirmation: {
onGoTo: onClickGoToMarketPlace,
},
}} />
You can use the themeOptions or theme props to pass a custom theme or theme options object:
themeOptions (preferred) will merge Mojito's default theme with your custom one
If none is provided, the default Mojito theme will be used.
const DefaultThemes: ThemeConfiguration = {
font: {
primary: 'Sneak',
secondary: 'Sneak',
},
color: {
primary: '#6663FD',
secondary: '#FFFFFF',
background: '#FAFAFC',
errorBackground: '#FEE3E5',
text: '#000000',
cardBackground: '#FFFFFF',
checkout: {
continueButtonBackground: '#6663FD',
continueButtonTextColor: '#FFFFFF',
},
placeholder: '#BABEC5',
costBreakdown: {
applyButtonBackground: '#DADAE9',
applyButtonTextColor: '#FFFFFF',
},
},
};
Note that using MUI's ThemeProvider from your project won't work as expected and you will end up seeing Mojito's default theme:
<MojitoCheckout theme={ theme }
If you are facing any issues regarding the Webpack polyfill in React.js applications while integrating this SDK, please follow these steps:
Step 1: Run either npm install or yarn install.
Step 2:
a) Before running the app, execute the following script once.
b) Create a file named (filename).js in the root of the project folder and paste the code from this GitHub repository:
Development setup
Step 3: In the package.json, add a new script called "prebuild": "node {name of the js file that you added}" and run the command npm run prebuild.
Step 4: Now, you can run the application.