third-party-perlas-init
v1.0.29
Published
> Perlas Payments widget.
Downloads
13
Readme
third-party-perlas-init
Perlas Payments widget.
Install
yarn add third-party-perlas-init / npm install third-party-perlas-init
Usage
/** @jsx jsx */
// Step 1. Import needed functions
import { getPerlasDataForInit, initPerlas } from "third-party-perlas-init";
import { useLocation } from "react-router-dom";
const {
location: { origin = "", href = "" },
} = window;
// Step 2. In the component pass required data to get src and formed object to pass into iframe via postmessage
const { src, data } = getPerlasDataForInit({
accessToken: JSON.parse(xhr?.response)?.access_token, //required,
parentWholeUrl: new URL(href), //required
environment: "test" //required
externalPaymentUrl: "https://www.aaa.lt", // If provided, must start with "https://". If provided, no cash payment option will be available. If provided, the bank-payment button will redirect here
fontFamily: "Montserrat", // If provided without fontFamilyUrls options, google font will be used.
fontFamilyUrls: {
// Two options to provide your custom fonts: regular and bold. If this is provided, provide fontFamily prop above as well.
regular: {
ttf: "https://test-api-public.perlas.lt/storage/fonts/skud-webfont.ttf",
woff: "https://test-api-public.perlas.lt/storage/fonts/skud-webfont.woff",
},
bold: {
ttf: "https://test-api-public.perlas.lt/storage/fonts/skud-webfont.ttf",
woff: "https://test-api-public.perlas.lt/storage/fonts/skud-webfont.woff",
},
},
fontSizes: {
// defaultFonts object added after PerlasGoThirdPartyInit function
// in the project mainly these are used: button, h3, h4, h5 (main project title), h6, subtitle1, body1 (main text size in app), body2 and caption (small text)
// changing font weights or line heights might not affect every element as there are custom stylings added or other cases, but it should be okay with font sizes and other props like (general fontSize, htmlFontSize)
// changing font family for each item is not possible because if custom fontFamily will be provided, this will be used for all items
// more info on typogrpahy provided here: https://mui.com/material-ui/customization/typography/
// pass custom values that you would like to overwrite like so below (as from what has been tested, no need to provide all values (f.e. fontWeight, lineHeight) if only for example fontSize needs to be changed):
button: {
fontSize: "0.8rem",
},
body1: {
fontSize: "1rem",
},
subtitle1: {
fontSize: "1.25rem",
lineHeight: 1.5,
},
h5: {
fontSize: "1.7rem",
lineHeight: 1.5,
},
h6: {
fontSize: "1.25rem",
lineHeight: 1.7,
},
},
imageUrls: {
success:
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // successfull payment image
failure:
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // failed payment image
paymentHistory:
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", // mobile payment history image
firstPayment:
"https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg", //make first payment image
},
serviceIconsColors: {
// defaultServiceIcons added just after PerlasGoThirdPartyInit function
electricity: { color: "#f9ec4b", stroke: "#7c702c" },
telecommunications: { color: "#d742f5", stroke: "#4287f5" },
financialServices: { color: "#d742f5", stroke: "#42f55a" },
},
palette: {
// provide colors as below to overwrite them (defaultPalette added after PerlasGoThirdPartyInit function)
// more info on palette provided here: https://mui.com/material-ui/customization/palette/
primary: {
main: "#f54281",
contrastText: "#fff",
dark: "#a8327b",
light: "#050105",
},
secondary: {
main: "#fcba03", //secondary white btn color
contrastText: "#505f6a",
dark: "#e9f022", // not used directly
light: "#ffffff", // not used directly
//contrastText is not used directly but necessary for text in secondary btn
},
background: {
default: "#f8f6f5",
},
neutral: {
main: "#d5e3eb",
},
},
hideMobileScrollbar: true,
serviceId: "350",
orderId: new URLSearchParams(useLocation().search).get("transOrderId") || "",
canceled: Boolean(
Number(new URLSearchParams(useLocation().search).get("cancel"))
),
isPdfNeededForApp: true,
});
// Step 3. (Optional) - Initialise widget by this function below. It passes data to iframe and initialises post message listening in parent page (listening message events from iframe). Initialise only after src and data exist.
useEffect(() => {
if (src && data) {
initPerlas({ src, data });
}
}, [src, data]);
render(
// Step 4. Add iframe with id="perlasgo-third-party"
!!src && (
<iframe
title="third-party"
style={{ width: "100%", height: "100%", minHeight: "100vh" }}
id="perlasgo-third-party"
src={src}
></iframe>
)
);
getPerlasDataForInit parameters
| Parameter | Required | Description | Possible Values | | ------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | accessToken | true | The access token you get from the 4th step in the official documentation in string format | JSON.parse( xhr?.response )?.access_token | | parentWholeUrl | true | The URL of the parent page, in which this iframe is being initialised | new URL( href ), | | environment | true | A string, describing the environment to which the requests from the widget will be made | "test", "sandbox", "staging", 'prod" | | buttonRadius | false | Value in pixels, describing the border radius of buttons. Defaults to 6px | 0-50 | | externalPaymentUrl | false | The url ( must be provided with the full protocol ( "https://..." ) ) to the external payment site.If provided, the user will not be able to access cash payments ( only bank payments will be accessible ).When the user clicks on bank payment button, he will be redirected to this url | "https://..." | | fontFamily | false | The name of the font family. If this is provided without fontFamilyUrls param, then the google fonts api will be used ( the app will search for the same name in google-fonts cdn ). | "Montserrat" ( or any other font-name ) | | fontFamilyUrls | false | Object containing two child objects: regular; bold. Each of the child objects accepts parameters in such format [FONT_FORMAT]: "https://test-api-public.perlas.lt/storage/fonts/name-of-thefont-webfont.[FONT_FORMAT]", where FONT_FORMAT is ttf / otf / woff / woff2 / eot. If provided, then fontFamily prop must be provided as well | See example above ( Usage section ) | | fontSizes | false | An Object containing the fontSizes of different elements in the App in the following format: [OBJECT_NAME]: {fontSize: "xrem", lineHeight: number}. When providing a particular object, the lineHeight prop is optional. Changing font weights or line heights might not affect every element as there are custom stylings added to some elements. The possible OBJECT_VALUES are described in the "Possible Values" column | button, h3, h4,h5, h6, subtitle1, body1, body2, caption | | imageUrls | false | An Object, containing four parameters (see "Possible Values" column), in the following format: [PARAMETER]: "https://some-link-to-your-image.svg". The images should be in svg format and take full height. | success ( shown after successful payment redirect ), failure ( shown after failed / canceled payment redirect ), paymentHistory ( shown on empty history page), firstPayment ( shown on empty cart page ) | | serviceIcosColors | false | An object containing the colors of service icons. ( see "Possible Values" column ). Icon needs both color and stroke properties in such format: [SERVICE_ICON] : { color: "#FFF", stroke: "#000" } | electricitygas waterheathouseCaretelecommunicationsfinancialServicessecurityeducationdirectPaymentfishinginvoicesothergarbage | | palette | false | An Object described in the Default objects section below. You are able to overwrite the default values here | See example above ( Usage section ) | | serviceId | false | A string, that perlas team provided for you, ( your serviceProvider id in our system), it will be used to redirect to the edit-service page, if the first cart has a service with this serviceId | "123" or any numeric value, that perlas team provided for you | | orderId | false | String value of the transOrderId from the URI. ( After payment with MIP, you will be redirected to the same page which contains the iframe, but with transOrderId search param attached and the iframe will be reinitialized ). You need to pass that param here, because the application cannot access the URI from inside the iframe. | new URLSearchParams( useLocation().search ).get( "transOrderId" ) | | canceled | false | Boolean value of the cancel enum from the URI. ( After a failed payment with MIP, you will be redirected to the same page which contains the iframe, but with transOrderId and cancel=1 search params attached and the iframe will be reinitialized ). You need to convert the cancel search param value into a boolean and pass it here, because the application cannot access the URI from inside the iframe. If passed, then orderId must be passed as well | Boolean( Number( new URLSearchParams( useLocation().search ).get( "cancel" ) ) | | isPdfNeededForApp | false | determines if the "pdf-download" event ( described in the events section below ) is fired | true / false | | hideMobileScrollbar | false | hide the scrollbar when iframe width is < 992px | true / false |
Default objects that could be overwritten and additional info
/** @jsx jsx */
const defaultPalette = {
mode: "light", // dark mode not currently implemented
primary: {
main: "#11c49c", //main green color throughout whole app
contrastText: "#fff", //contrastText is not used directly but necessary for text in primary btn
dark: "#0B896D",
light: "#40CFAF",
},
secondary: {
main: "#ffffff", //secondary white btn color
contrastText: "#505f6a", //contrastText is not used directly but necessary for text in secondary btn
dark: "#d5e3eb", //secondary white hover btn color
light: "#ffffff", // not used directly
},
white: {
main: "#ffffff",
contrastText: "#a1abb9",
dark: "#d5e3eb", // not used directly
light: "#ffffff", // not used directly
},
neutral: {
main: "#d5e3eb",
contrastText: "#505f6a",
},
card: {
main: "#ffffff", //used for background when not active and icon stroke color when active
light: "#d5e3eb", //used for card hover background
dark: "#505f6a", //used for active card background,
contrastText: "#ffffff", // text color when active and icon stroke
},
azureishWhite: {
main: "#d5e3eb", //used in dashboard toggle buttons, reg banner, button and etc
},
background: {
default: "#f2f6f9", // blueish background main
paper: "#ffffff", // white color background
},
//blue color
blueBayoux: {
main: "#4b6374",
},
//toast colors
error: {
main: "#c74a4a", //toast error color or other errors colo
dark: "#dc143c", //used in error messages, history bar chart arrows
light: "rgb(210, 110, 110)",
contrastText: "#fff",
},
success: {
main: "#11c49c", //toast succes color
light: "rgb(64, 207, 175)",
dark: "rgb(11, 137, 109)",
contrastText: "rgba(0, 0, 0, 0.87)",
},
warning: {
main: "#f1c40f", //toast warn color
light: "rgb(243, 207, 63)",
dark: "rgb(168, 137, 10)",
contrastText: "rgba(0, 0, 0, 0.87)",
},
text: {
primary: "#000000", // text color -black
secondary: "#505f6a", // text secondary color darker grey
disabled: "#a1abb9", //text disabled color grey
},
//grey colors
shuttleGray: {
main: "#505f6a", //used in various places through web/3rd party
},
gullGray: {
main: "#a1abb9", //used in various places through web/3rd party
},
mysticGray: {
main: "#dfe5eb", //used in 2 places
},
nobelGray: {
main: "#b6b5b5", //used in various places through web/3rd party
},
geyserGray: {
main: "#dbe0e7", //used in several places through web/3rd party
},
//black and the other
black: {
main: "#000000",
},
common: {
black: "#000",
white: "#fff",
},
contrastThreshold: 3,
tonalOffset: 0.2,
divider: "rgba(0, 0, 0, 0.12)",
action: {
active: "rgba(0, 0, 0, 0.54)",
hover: "rgba(0, 0, 0, 0.04)",
hoverOpacity: 0.04,
selected: "rgba(0, 0, 0, 0.08)",
selectedOpacity: 0.08,
disabled: "rgba(0, 0, 0, 0.26)",
disabledBackground: "rgba(0, 0, 0, 0.12)",
disabledOpacity: 0.38,
focus: "rgba(0, 0, 0, 0.12)",
focusOpacity: 0.12,
activatedOpacity: 0.12,
},
},
const defaultServiceIcons = {
electricity: { color: "#f9ec4b", stroke: "#7c702c" },
gas: { color: "#fcf6a5", stroke: "#aa9a3c" },
water: { color: "#02c19d", stroke: "#107a66" },
heat: { color: "#418c94", stroke: "#8bd8d6" },
houseCare: { color: "#7c702c", stroke: "#d8c564" },
telecommunications: { color: "#81e0ce", stroke: "#379b88" },
financialServices: { color: "#cc6e52", stroke: "#eaddc1" },
security: { color: "#cf9f5e", stroke: "#593109" },
education: { color: "#c0efe7", stroke: "#64a095" },
directPayment: { color: "#5B998D", stroke: "#7CB5AA" },
fishing: { color: "#a89d38", stroke: "#fcf6a5" },
invoices: { color: "#726928", stroke: "#fdfad2" },
other: { color: "#026670", stroke: "#c0d9db" },
garbage: { color: "#e2ad37", stroke: "#7f4011" },
};
const defaultFonts = {
fontSize: 14,
htmlFontSize: 16,
button: {
fontSize: "0.875rem",
textTransform: "none",
fontFamily: "Inter, sans-serif",
fontWeight: 500,
lineHeight: 1.75,
},
fontWeightExtraBold: 800,
fontWeightSemiBold: 600,
subtitle1: {
fontSize: "1.125rem",
fontFamily: "Inter, sans-serif",
fontWeight: 400,
lineHeight: 1.75,
},
fontWeightLight: 300,
fontWeightRegular: 400,
fontWeightMedium: 500,
fontWeightBold: 700,
h1: {
fontFamily: "Inter, sans-serif",
fontWeight: 300,
fontSize: "6rem",
lineHeight: 1.167,
},
h2: {
fontFamily: "Inter, sans-serif",
fontWeight: 300,
fontSize: "3.75rem",
lineHeight: 1.2,
},
h3: {
fontWeight: 400,
fontSize: "3rem",
lineHeight: 1.167,
},
h4: {
fontWeight: 400,
fontSize: "2.125rem",
lineHeight: 1.235,
},
h5: {
fontFamily: "Inter, sans-serif",
fontWeight: 400,
fontSize: "1.5rem",
lineHeight: 1.334,
},
h6: {
fontFamily: "Inter, sans-serif",
fontWeight: 500,
fontSize: "1.25rem",
lineHeight: 1.6,
},
subtitle2: {
fontFamily: "Inter, sans-serif",
fontWeight: 500,
fontSize: "0.875rem",
lineHeight: 1.57,
},
body1: {
fontFamily: "Inter, sans-serif",
fontWeight: 400,
fontSize: "1rem",
lineHeight: 1.5,
},
body2: {
fontFamily: "Inter, sans-serif",
fontWeight: 400,
fontSize: "0.875rem",
lineHeight: 1.43,
},
caption: {
fontFamily: "Inter, sans-serif",
fontWeight: 400,
fontSize: "0.75rem",
lineHeight: 1.66,
},
};
Events
Events can be sent both by third party to parent and from parent to third party
By parent to third party below:
Sending events to third party from parent could be done using function sendEventToThirdParty({{ src, eventType, data }}). src is from getPerlasDataForInit function. Currently third party is listening to only one event from parent (redirect from received barcode). All events share same type "third-party". Example how to send data from parent to third party below:
/** @jsx jsx */
import { sendEventToThirdParty } from "third-party-perlas-init";
sendEventToThirdParty({
src,
eventType: "redirect",
data: { barcode: "xxads1231123" },
});
//or something like this if implementing differently
const iframe = document.getElementById("perlasgo-third-party");
iframe.contentWindow.postMessage(
{ type: "third-party", eventType, data },
environmentUrl
);
Currently these events below are sent by third party to parent
/** @jsx jsx */
window.parent.postMessage(
{ message: "page-loading", eventType: "info", type: "third-party" }, // <- when page receives needed data for initializiation and starts to load everything, no succesfull API request is made yet
parentOriginUrl
);
window.parent.postMessage(
{ message: "client-info-loaded", eventType: "info", type: "third-party" }, // <- when first successfull API request is finished to get client data
attributesObject.parentOriginUrl
);
window.parent.postMessage(
{
data: {
data: arrayBufferToBase64(data), // if isPdfNeededForApp prop is set as true for application, when on PDF downloads ArrayBuffer of pdf will be converted to base64 and sent to parent
fileName,
},
eventType: "pdf-download",
type: "third-party",
},
attributesObject.parentOriginUrl
);
window.parent.postMessage(
{ url: res.url, eventType: "redirect", type: "third-party" }, // if no externalPaymentUrl prop is set for application, when pay button is pressed it, third party will send back to parent event with info where to redirect
parentOriginUrl
);
window.parent.postMessage(
{
url: externalPaymentUrl + "?orderId=" + id, // if externalPaymentUrl prop is set for application, when pay button is pressed it, third party will send back to parent event with info where to redirect where url will be externalPaymentUrl with orderId attached
eventType: "redirect",
type: "third-party",
},
parentOriginUrl
);