UNPKG

react-native-cashfree-pg-sdk

Version:
240 lines (239 loc) 7.44 kB
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } import { TextInput } from 'react-native'; import React, { forwardRef } from 'react'; import { CFSubsCardPayment, CFEnvironment } from 'cashfree-pg-api-contract'; import { CFPaymentGatewayService } from '../index'; function luhnCheck(cardNumber) { if (cardNumber.length === 0) { return false; } cardNumber = cardNumber.replace(/\s/g, ''); let sum = 0; let isAlternate = false; for (let i = cardNumber.length - 1; i >= 0; i--) { let digit = parseInt(cardNumber[i], 10); if (isAlternate) { digit *= 2; if (digit > 9) { digit -= 9; } } sum += digit; isAlternate = !isAlternate; } return sum % 10 === 0; } function getInputValidationDetails(cardBinResponse) { if (!cardBinResponse || !cardBinResponse.scheme) { return null; } const schemeType = cardBinResponse.scheme.toLowerCase(); let inputValidationDetails; switch (schemeType) { case 'amex': inputValidationDetails = { max_input_length: 15, cvv_length: 4 }; break; case 'diners': inputValidationDetails = { max_input_length: 14, cvv_length: 3 }; break; default: // Covers visa, mastercard, rupay, jcb, discover, and unknown schemes inputValidationDetails = { max_input_length: 16, cvv_length: 3 }; } return inputValidationDetails; } /** * Fetching CardBin info with card bin data & CFSubscriptionSession object * @param session : for subs sessionId & env * @param bin : for card number */ async function getCardBin(session, bin) { const route = `/pg/sdk/js/subscription/card/bin`; const body = JSON.stringify({ card_number: bin }); let baseUrl = 'https://api.cashfree.com'; if (session.environment === CFEnvironment.SANDBOX) { baseUrl = 'https://sandbox.cashfree.com'; } const url = baseUrl + route; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-sub-session-id': session.subscription_session_id }, body }); if (!response.ok) { return null; } return await response.json(); } catch (error) { return null; } } const SubsCardInput = /*#__PURE__*/forwardRef(({ cfSubscriptionSession, cardListener, style, ...props }, ref) => { const [inputNumber, setInputNumber] = React.useState(''); const inputNumberRef = React.useRef(''); const sessionRef = React.useRef(cfSubscriptionSession); React.useImperativeHandle(ref, () => ({ doSubscriptionPayment, doSubscriptionPaymentWithNewSession })); const cardBinJsonRef = React.useRef(null); const firstEightDigitsRef = React.useRef(''); const handleChange = React.useCallback(async cardNumber => { let completeResponse = {}; const textWithoutSpaces = cardNumber.replaceAll(' ', ''); if (textWithoutSpaces.length === 0) setInputNumber(''); let formattedText = ''; for (let i = 0; i < textWithoutSpaces.length; i += 4) { let end = i + 4; if (end > textWithoutSpaces.length) { end = textWithoutSpaces.length; } formattedText += textWithoutSpaces.substring(i, end); if (end !== textWithoutSpaces.length) { formattedText += ' '; } inputNumberRef.current = formattedText; setInputNumber(prev => prev === formattedText ? prev : formattedText); } let cardBinResponse = null; async function fetchCardBinAndSet() { await getCardBin(cfSubscriptionSession, textWithoutSpaces).then(response => { cardBinResponse = response; firstEightDigitsRef.current = textWithoutSpaces.substring(0, 8); }).catch(() => { cardBinResponse = null; }); if (cardBinResponse) { cardBinJsonRef.current = cardBinResponse; completeResponse.card_bin_info = cardBinJsonRef.current; completeResponse.input_validation = getInputValidationDetails(cardBinJsonRef.current); } } if (textWithoutSpaces.length === 8) { await fetchCardBinAndSet(); } else if (textWithoutSpaces.length > 8) { if (firstEightDigitsRef.current === textWithoutSpaces.substring(0, 8)) { completeResponse.card_bin_info = cardBinJsonRef.current; completeResponse.input_validation = getInputValidationDetails(cardBinJsonRef.current); } else { cardBinJsonRef.current = null; await fetchCardBinAndSet(); } } if (textWithoutSpaces.length < 8) { cardBinJsonRef.current = null; firstEightDigitsRef.current = ''; } if (cardBinJsonRef.current !== null) { completeResponse.card_network = cardBinJsonRef.current.scheme; } let luhnStatus = luhnCheck(textWithoutSpaces); if (luhnStatus) { completeResponse.luhn_check_info = 'SUCCESS'; if (textWithoutSpaces && textWithoutSpaces.length > 4) { completeResponse.last_four_digit = textWithoutSpaces.substring(textWithoutSpaces.length - 4); } } else { completeResponse.luhn_check_info = 'FAIL'; } completeResponse.card_length = textWithoutSpaces.length; return cardListener(JSON.stringify(completeResponse)); }, [cfSubscriptionSession, cardListener]); const doSubscriptionPayment = cardInfo => { try { let cfCardNumber = inputNumberRef.current; cardInfo.cardNumber = cfCardNumber.replaceAll(' ', ''); const cardPayment = new CFSubsCardPayment(sessionRef.current, cardInfo); CFPaymentGatewayService.makeSubsPayment(cardPayment); } catch (e) { console.log(e.message); } }; const doSubscriptionPaymentWithNewSession = (cardInfo, session) => { try { sessionRef.current = session; doSubscriptionPayment(cardInfo); } catch (e) { console.log(e.message); } }; const handleSubmitEditingEvent = event => { const newEvent = { ...event }; delete newEvent.nativeEvent.text; if (onSubmitEditing) { onSubmitEditing(newEvent); } }; const handleEndEditingEvent = event => { const newEvent = { ...event }; delete newEvent.nativeEvent.text; if (onEndEditing) { onEndEditing(newEvent); } }; const handleFocusEvent = event => { const newEvent = { ...event }; delete newEvent.nativeEvent.text; if (onFocus) { onFocus(newEvent); } }; const handleBlurEvent = event => { const newEvent = { ...event }; delete newEvent.nativeEvent.text; if (onBlur) { onBlur(newEvent); } }; const InputComponent = TextInput; const { onChangeText, onChange, onSubmitEditing, onEndEditing, onFocus, onBlur, ...otherProps } = props; return /*#__PURE__*/React.createElement(InputComponent, _extends({ keyboardType: "numeric", inputMode: 'numeric', value: inputNumber, onChangeText: handleChange, onSubmitEditing: handleSubmitEditingEvent, onEndEditing: handleEndEditingEvent, onFocus: handleFocusEvent, onBlur: handleBlurEvent, style: style }, otherProps)); }); export default SubsCardInput; //# sourceMappingURL=CFSubsCardComponent.js.map