На главную
Использование
Установка:
Добавьте тэг <script> в ваш index.html:
<script src="https://dev-sdk.paybetget.cash/0-0-17/sdk.js"></script>
Принцип работы:
SDK добавляет в window новый объект: paymentWidgetSDK.
В нём есть метод render. Его можно вызывать множество раз, работает как render в React (и похожих библиотеках).
Для работы виджета нужно передать ряд данных о вашем приложении:
- Название бренда вашего приложения (напр. “mostbet”)
- Код сайта. Он сообщает какой именно бэкенд используется. Например “mostbet” для production и “mostbet_dev17” для dev стенда.
- Payment token. Это токен, который нужен для общения с бэком виджета. Его получает ваше приложение у вашего же бэка.
- Тип виджета. Пополнение или вывод денег. Если пользователь пополняет счёт - значит “refill”, если выводит деньги - значит “payout”
- Валюта пользователя. Пользователь в вашем приложении выбрал валюту с которой работает. Вот её нужно передать.
- Окружение: дев стенд или продакшн.
Полный список параметров:
export interface Options {
/**
* Контейнер для виджета. Может быть HTMLElement или CSS-селектор.
* В этот контейнер добавится iframe в котором отобразится виджет
*/
container: Container;
/**
* Этим свойством регулируем стили и прочие особенности для конкретного бренда.
* Например вы работаете над сайтом 'mostbet.com', значит сюда надо передать 'mostbet'.
* Таким образом виждет будет отображаться со стилями предназначенными для вашего сайта.
*/
brand: string;
/**
* Код вашего сайта, указывающий на конкретный API для использования.
* Например `mostbet` или `mostbet_dev17`
*/
siteCode: string;
/**
* Тип виджета - пополнение или вывод
*/
widgetType: WidgetType;
/** Текущая валюта пользователя. Нужно для аналитики */
userCurrency: string | null | undefined;
/** Показать / скрыть виджет */
isVisible: boolean;
/**
* Перед каждым запросом на бэк, виджету нужно иметь токен.
* Как правило он получается вами от вашего бэка.
* При любом изменении пользователя, его настроек, нужно получить новый токен.
* `null` означает, что токен запросили, но пока не получен.
* В этом случае виджет покажет экран загрузки.
*/
paymentToken: string | null;
/**
* Подписка на события виджета: редиректы, запрос открытия страниц настроек и прочее:
*
*
* https://confluence.dats.tech/pages/viewpage.action?pageId=809240783
*/
onWidgetEvent?: (event: WidgetEvent) => void;
/**
* имя css класса для iframe
*/
className?: string;
/**
* Функция для отправки GET запросов к API.
* Если у вас модифицирован `fetch` (старые версии next.js) или вы хотите
* как-то модифицировать запросы - передайте сюда свою функцию.
* @default window.fetch
*/
makeGetRequest?: (url: string) => Promise<
{
status?: number;
statusText?: string;
} & (
| {
data: unknown;
}
| {
json: () => Promise<unknown>;
}
)
>;
/**
* Функция для отправки аналитики
*/
rstatPushHandler?: (eventName: string, eventData: Record<string, unknown>) => void;
/**
* Определяет к какому API будет стучаться виджет, к проду или деву:
*
* dev: апи запросы шлёт в 'https://dev.paybet.cash', либо в dev указаный
* в куке `PW_DEV`, например 'https://dev-1.paybet.cash'
* prod: апи запросы шлёт в 'https://paybet.cash'
*
*/
environment: 'dev' | 'prod';
}
Для показа виджета нужно вызвать paymentWidgetSDK.render(options). При каждом изменении options следует вызывать paymentWidgetSDK.render(options), чтобы UI всегда был синхронизирован. Его можно вызывать много раз, если значения внутри options не изменились, то и виджет ничего не сделает.
Чтобы скрыть/показать виджет, просто поменяйте значение isVisible и вызовите render
События виджета
В некоторых случаях виджет должен осуществлять редирект на страницы вашего приложения
Для этого воспользуйтесь параметром Options['onWidgetEvent']:
paymentWidgetSDK.render({
...options,
onWidgetEvent: (event) => {
switch (event.type) {
case 'PW_WIDGET_CLOSE':
window.location.assign('/');
return;
case 'PW_WIDGET_OPEN_RULES_PAGE':
window.location.assing('/rules');
return;
case 'PW_WIDGET_OPEN_PROFILE_EDIT_PAGE':
window.location.assing('/profile');
return;
case 'PW_WIDGET_OPEN_BONUS_PROGRESS':
window.location.assing('/bonuses');
return;
default:
return;
}
}
})
Полный список методов:
export interface PaymentWidgetSDK {
render: Render;
/**
* Отмонтирует, монтирует заново и рендерит виджет.
* Для случаев когда есть некий баг и рассинхронизированный UI
*/
reset: Reset;
/**
* Метод для отправки сообщений виджету.
* В настоящее время в ней не должно быть необходимости,
* всё делается на стороне sdk.
* Но в будущем это может измениться
*/
sendWidgetEvent: SendWidgetEvent;
/** Текущая версия виджета */
version: string;
/**
* Метод для удаления виджета из DOM и очистки памяти.
* Повторный вызов `render` снова добавит виджет.
*/
unmount: () => void;
}
Использование в React приложении:
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useRequest } from 'some-fetching-library';
export const PaymentWidget = ({
userCurrency,
isVisible,
onClose,
}: {
userCurrency: string | null;
isVisible: boolean
onClose: () => void
}) => {
const [container, setContainer] = useState<HTMLDivElement | null>(null);
/**
* @type {{ paymentToken: string | null }}
*/
const { data: paymentToken = null } = useRequest(async () => {
const response = await fetch(new URL('/api/get-payment-token', window.location.origin));
const { paymentToken } = await response.json();
return paymentToken;
});
useEffect(() => {
return () => {
window.paymentWidgetSDK.unmount();
};
}, []);
const navigate = useNavigate();
useEffect(() => {
if (!container) {
window.paymentWidgetSDK.unmount();
return;
}
window.paymentWidgetSDK.render({
container,
brand: 'my_brand',
siteCode: 'my_brand_site_code',
widgetType: 'refill',
environment: import.meta.env.DEV ? 'dev' : 'prod',
paymentToken,
userCurrency,
isVisible,
onWidgetEvent: (event) => {
switch (event.type) {
case 'PW_WIDGET_CLOSE':
onClose();
return;
case 'PW_WIDGET_OPEN_RULES_PAGE':
navigate('/rules');
return;
case 'PW_WIDGET_OPEN_PROFILE_EDIT_PAGE':
navigate('/profile');
return;
case 'PW_WIDGET_OPEN_BONUS_PROGRESS':
navigate('/progress');
return;
default:
return;
}
},
});
}, [paymentToken, userCurrency, isVisible, onWidgetEvent, container]);
return <div ref={setContainer} />;
};
Typescript
Опреледения типов можно скачать отсюда:
curl https://dev-sdk.paybetget.cash/0-0-17/sdk.d.ts -o ./sdk.d.ts
Или просто скопируйте себе это:
/**
* Payment Widget SDK Type Definitions
* Version: 0.0.17
*/
/**
* Контейнер для виджета. Может быть HTMLElement или CSS-селектором
*/
export declare type Container = HTMLElement | CSSSelector;
export declare type CSSSelector = string;
declare type GetRequestFunction = (url: string) => Promise<{
status?: number;
statusText?: string;
} & ({
data: unknown;
} | {
json: () => Promise<unknown>;
})>;
declare type MessageFromWidget = {
/**
* Это сообщение означает, что приложение или не нашло в своём сторе токен,
* или только запустилось.
* То есть это не запрос на получение нового токена,
* а просто такой вот getter
*/
type: 'TOKEN_REQUEST';
payload: null;
} | {
type: 'PW_WIDGET_CLOSE';
payload: null;
} | {
type: 'PW_WIDGET_OPEN_RULES_PAGE';
payload: null;
} | {
type: 'PW_WIDGET_OPEN_PROFILE_EDIT_PAGE';
payload: null;
} | {
type: 'PW_WIDGET_REDIRECT_WITH_POPUP_VALUE';
payload: {
url: string;
};
} | {
type: 'PW_WIDGET_REDIRECT';
payload: {
url: string;
};
} | {
type: 'PW_WIDGET_REDIRECT_IN_NEW_TAB';
payload: {
url: string;
};
} | {
type: 'PW_WIDGET_IFRAME_LOADER_READY';
payload: null;
} | {
type: 'PW_WIDGET_OPEN_BONUS_PROGRESS';
payload: null;
} | {
type: 'PW_WIDGET_NOTIFICATION_REFILL';
payload: {
refillId: string;
userId?: string;
};
} | {
type: 'PW_WIDGET_NOTIFICATION_PAYOUT';
payload: {
payoutId: string;
userId?: string;
};
};
declare type MessageToWidget = {
type: 'PW_WIDGET_UPDATE_TOKEN';
payload: {
token: string;
};
} | {
type: 'PW_WIDGET_CLOSE';
payload: null;
} | {
type: 'PW_WIDGET_OPEN';
payload: {
token: string;
widgetType: WidgetType_2;
};
};
export declare interface Options {
/**
* Контейнер для виджета. Может быть HTMLElement или CSS-селектором.
* В этот контейнер добавится iframe в котором отобразится виджет
*/
container: Container;
/**
* Этим свойством регулируем стили и прочие особенности для конкретного бренда.
* Например вы работаете над сайтом 'mostbet.com',
* значит сюда надо передать 'mostbet'.
* Таким образом виждет будет отображаться со стилями предназначенными
* для вашего сайта.
*/
brand: string;
/**
* Код вашего сайта.
* Указывает на конкретный API для использования.
* Например `mostbet` или `mostbet_dev17`
*/
siteCode: string;
/**
* Тип виджета - пополнение, вывод и т.п.
*/
widgetType: WidgetType;
/** Текущая валюта пользователя. Нужно для аналитики */
userCurrency: string | null | undefined;
/** Показать / скрыть виджет */
isVisible: boolean;
/**
* Перед каждым запросом на бэк, виджету нужно иметь токен.
* Как правило он получается вами от вашего бэка.
* При любом изменении пользователя, его настроек, нужно получить новый токен.
* Проще всего получать токен при каждом открытии виджета (изменении `isVisible`)
* `null` означает, что токен запросили, но пока не получен
*/
paymentToken: string | null;
/**
* Подписка на события виджета: редиректы, запрос открытия страниц настроек и прочее:
*
*
* https://confluence.dats.tech/pages/viewpage.action?pageId=809240783
*/
onWidgetEvent?: (event: WidgetEvent) => void;
/**
* имя css класса для iframe
*/
className?: string;
/**
* Функция для отправки GET запросов к API.
* Если у вас модифицирован `fetch` (старые версии next.js) или вы хотите
* как-то модифицировать запросы - передайте сюда свою функцию.
* @default window.fetch
*/
makeGetRequest?: GetRequestFunction;
/**
* Функция для отправки аналитики
*/
rstatPushHandler?: (eventName: string, eventData: Record<string, unknown>) => void;
/**
* Определяет к какому API будет стучаться виджет, к проду или деву:
* ```
* dev: апи запросы шлёт в 'https://dev.paybet.cash', либо в dev указаный
* в куке `PW_DEV`
* prod: апи запросы шлёт в 'https://paybet.cash'
* ```
*/
environment: 'dev' | 'prod';
}
export declare interface PaymentWidgetSDK {
/**
* Монтирует, если нужно, и показывает виджет.
* При одинаковых Options ничего не делает.
*/
render: Render;
/**
* unmount + mount + render
*/
reset: Reset;
/**
* В настоящее время эта функция не нужна никому,
* всё делается на стороне sdk.
* Но в будущем это может измениться
*/
sendWidgetEvent: SendWidgetEvent;
/** Текущая версия виджета */
version: string;
/**
* Метод для удаления виджета из DOM и очистки памяти
*/
unmount: () => void;
}
declare type Render = (options: Options) => void;
declare type Reset = () => void;
export declare interface RStatCommonData {
page_type: 'widget';
currency?: string;
}
/**
* В настоящее время эта функция не нужна никому,
* всё делается на стороне sdk.
* Но в будущем это может измениться
*/
export declare type SendWidgetEvent = (event: MessageToWidget) => void;
export declare type WidgetEvent = Extract<MessageFromWidget, {
type: 'PW_WIDGET_CLOSE';
} | {
type: 'PW_WIDGET_OPEN_RULES_PAGE';
} | {
type: 'PW_WIDGET_OPEN_PROFILE_EDIT_PAGE';
} | {
type: 'PW_WIDGET_REDIRECT_WITH_POPUP_VALUE';
} | {
type: 'PW_WIDGET_IFRAME_LOADER_READY';
} | {
type: 'PW_WIDGET_OPEN_BONUS_PROGRESS';
} | {
type: 'PW_WIDGET_NOTIFICATION_REFILL';
} | {
type: 'PW_WIDGET_NOTIFICATION_PAYOUT';
}> | {
/**
* Срабатывает на iframe.onload
*/
type: 'IFRAME_LOADED';
payload: {
iframe: HTMLIFrameElement;
};
} | {
/**
* Срабатывает когда виджет добавлен в DOM, загрузил скрипты и получил token
*/
type: 'WIDGET_READY';
payload: {
iframe: HTMLIFrameElement;
};
} | {
type: 'SET_IFRAME_REF';
payload: {
iframe: HTMLIFrameElement | null;
};
};
export declare type WidgetType = 'payout' | 'refill';
declare type WidgetType_2 = 'refill' | 'payout';
export { }
;