UNPKG

react-native-tosspayments-v2

Version:
164 lines (163 loc) 4.98 kB
import { forwardRef, useImperativeHandle, useRef, useState } from 'react'; import WebView from 'react-native-webview'; import { TossPaymentsV2WidgetHtml } from "../html/TossPaymentsV2WidgetHtml.mjs"; import { View, Platform, Linking } from 'react-native'; import { useStableCallback } from "../util/useStableCallback.mjs"; import { is } from '@mj-studio/js-util'; /** * https://docs.tosspayments.com/sdk/v2/js#widgetsrequestpayment */ import { jsx as _jsx } from "react/jsx-runtime"; const TossPaymentsV2Widget = /*#__PURE__*/forwardRef(({ style, webViewProps, clientKey, customerKey, onPaymentFail, onPaymentSuccess, paymentRequest, onPaymentError, agreementVariantKey, paymentMethodsVariantKey }, ref) => { const [height, setHeight] = useState(400); const inner = useRef(null); const postMessage = ({ type, data }) => { inner.current?.injectJavaScript(`(function(){ window.dispatchEvent(new MessageEvent('message', {data : ${JSON.stringify({ type, data })}})) })()`); }; const setParams = useStableCallback((key, value) => { postMessage({ type: 'setParam', data: { key, value } }); }); const init = useStableCallback(() => { postMessage({ type: 'init' }); }); const onLoadWebView = useStableCallback(() => { setParams('clientKey', clientKey); setParams('customerKey', customerKey); const { amount, orderId, orderName, customerEmail, customerName, customerMobilePhone, card, taxFreeAmount } = paymentRequest; setParams('amount', amount); setParams('orderId', orderId); setParams('orderName', orderName); setParams('customerEmail', customerEmail); setParams('customerName', customerName); setParams('customerMobilePhone', customerMobilePhone); setParams('card', card); setParams('taxFreeAmount', taxFreeAmount); setParams('paymentMethodsVariantKey', paymentMethodsVariantKey || 'DEFAULT'); setParams('agreementVariantKey', agreementVariantKey || 'AGREEMENT'); init(); }); const onMessage = useStableCallback(event => { const rawData = event?.nativeEvent?.data; if (is.notEmptyString(rawData) && rawData.startsWith('{') && rawData.endsWith('}')) { const { type, data } = JSON.parse(rawData); if (type === 'requestPaymentFail' || type === 'unknownError') { onPaymentError?.(data); } else if (type === 'updateLayout') { const { scrollHeight } = data; setHeight(scrollHeight + 24); } } }); useImperativeHandle(ref, () => ({}), []); return /*#__PURE__*/_jsx(View, { style: [{ height }, style], children: /*#__PURE__*/_jsx(WebView, { ref: inner, textZoom: 100, contentMode: 'mobile', scalesPageToFit: true, showsHorizontalScrollIndicator: false, scrollEnabled: false, overScrollMode: 'never', ...webViewProps, onLoad: e => { webViewProps?.onLoad?.(e); onLoadWebView(); }, style: [{ opacity: 0.99 }, webViewProps?.style], source: { html: TossPaymentsV2WidgetHtml }, onMessage: onMessage, onShouldStartLoadWithRequest: ({ url }) => { if (url.startsWith('https://success')) { const params = new URL(url).searchParams; const paymentType = params.get('paymentType') || ''; const orderId = params.get('orderId') || ''; const paymentKey = params.get('paymentKey') || ''; const amount = Number(params.get('amount')); onPaymentSuccess({ amount, orderId, paymentKey, paymentType }); return false; } else if (url.startsWith('https://fail')) { const params = new URL(url).searchParams; const code = params.get('code') || ''; const message = params.get('message') || ''; const orderId = params.get('orderId') || ''; onPaymentFail({ code, message, orderId }); return false; } else if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('about:blank')) { return true; } else if (Platform.OS === 'android') { // AndroidIntentUtil.handleTossPaymentUrl(url).catch( // onFailedOpenISPApps // ); Linking.openURL(url).catch(onFailedOpenISPApps); } else if (Platform.OS === 'ios') { Linking.openURL(url).catch(onFailedOpenISPApps); } return true; function onFailedOpenISPApps() { console.log('카드사 결제앱 실행에 실패했어요\n설치 후 진행해주세요!'); } } }) }); }); export { TossPaymentsV2Widget }; //# sourceMappingURL=TossPaymentsV2Widget.mjs.map