import * as React from 'react'; import { connect } from "react-redux"; import { TouchableOpacity, View, Text, Image, Switch, StyleSheet, Modal, Alert, TextInput } from 'react-native'; import { WebView } from 'react-native-webview'; import { returnIcon } from '../../utils/card'; import moment from 'moment'; import cardValidator from 'card-validator'; import REQUEST_POST_PAY from '../../components/api/postpayapi'; import CustomHeader from '../../components/header.js'; import Theme from '../../components/theme.style.js'; import Elements from '../../components/elements.js'; import Assets from '../../components/assets.manager.js'; import Cipher from '../../components/cardencrypt/encryptcard'; import DB from '../../components/storage/'; import CustomSafeArea from '../../components/safeArea.component'; class PayatpumpPaymentMethodList extends React.Component { constructor(props) { super(props) } state = { cards: [], cardNumber: null, cardExpiry: null, cardCVV: null, cardZipcode: null, customerName: `${this.props.userinfo.data.firstname} ${this.props.userinfo.data.lastname}`, focus_holder: null, focus_expiry: false, focus_cvv: false, focus_zipcode: false, enableDefaultCard: false, showModal: false, pubkey: null, verificationUrl: null, cardDetails: null, loading: false } componentDidMount() { this.getWalletKey() } getWalletKey = async () => { this.setState({ loading: true }) REQUEST_POST_PAY('getWalletPublicKey', 'get', {}, {}, {}, async (res) => { this.setState({ loading: false }) if(res.status) { this.setState({ pubkey: res.data.publicKey }) } else { setTimeout(() => { Alert.alert("Information", '\n' + 'Failed to get fund. Try again.') }, 300) } }, (error) => { this.setState({ loading: false }) setTimeout(() => { Alert.alert("Information", '\n' + 'Failed to get fund. Try again.') }, 300) }) } addCard = async (cardDetails, publicKey, cardHolder, onSuccess, onError) => { REQUEST_POST_PAY('getFunding', 'post', {}, {}, {}, async (res) => { const cardNumber = this.state.cardNumber.replace(/ /g, "").toString(); const wallets = res.data.wallets.find(wallets => wallets.fundingProviderName === "p97token").wallets; // const filteredWallets = wallets.find(wallet => cardNumber.includes(wallet.firstSix) && cardNumber.includes(wallet.lastFour)); // if(filteredWallets) { // return onError("Card number already exist.") // } else { this.setState({ loading: false }) const firstSix = cardDetails.pan.slice(0, 6) const lastSix = cardDetails.pan.slice(-4) const expMonth = cardDetails.expDate.slice(0,2); const expYear = cardDetails.expDate.slice(-2); let params = { first_six: firstSix, last_four: lastSix, cvv: cardDetails.cvv, expire: `${expMonth}${expYear}`, ecd: publicKey, zip_code: cardDetails.zipcode } REQUEST_POST_PAY('addCreditCard', 'post', {}, {}, params, (res) => { if(res.status) { if(res.data.result) { this.addCardProviderData(res.data.referenceNumber, cardHolder, onSuccessResponse => onSuccess(onSuccessResponse), onErrorResponse => onError(onErrorResponse)) } } else { onError('Failed to add new card. Try again.') } }, (error) => { onError(error) }) // } }, () => { onError("Something went wrong, please try again.") }) } addCardProviderData = async (referenceNumber, cardHolder, onSuccess, onError) => { let params = { referenceNumber: referenceNumber, providerData: { nickName: "Paymaya Visa", firstName: cardHolder } } const USER_PROFILE = await DB.profile() REQUEST_POST_PAY('addCreditCard', 'post', { token: USER_PROFILE.data.auth_p97 }, {}, params, (res) => { if(res.success == undefined) { onError(res.Message) } else { if(res.success) { if(res.response.result) { onSuccess({ referenceNumber: res.response.referenceNumber, verificationUrl: res.response.stepWiseResponsePayload.verificationUrl }) } } else { onError('Failed to add new card. Try again.') } } }, (error) => { onError(error) }) } _handlingCustomerName = (name) => { this.setState({ customerName: name }) } _handlingCardNumber = (number) => { var value = number.replace(/\s+/g, '').replace(/[^0-9]/gi, '') var matches = value.match(/\d{4,16}/g); var match = matches && matches[0] || '' var parts = [] for (let i = 0, len=match.length; i { if (number.indexOf('.') >= 0 || number.length > 5) return if (number.length === 2 && this.state.cardExpiry.length === 1) number += '/' this.setState({ cardExpiry: number }); } _handlingCVV = (number) => { if (number.indexOf('.') >= 0 || number.length > 3) return this.setState({ cardCVV: number }); } _handlingZipCode = (number) => { if (number.indexOf('.') >= 0 || number.length > 4) return this.setState({ cardZipcode: number }); } _onAuthenticationSuccess = async (referenceNumber, callback) => { this.props.route?.params.onSetLoading(); let params = { referenceNumber: referenceNumber, } this.setState({ loading: true }) const USER_PROFILE = await DB.profile() REQUEST_POST_PAY('addCreditCard', 'post', { token: USER_PROFILE.data.auth_p97 }, {}, params, (res) => { console.log(res) if(res.success == undefined) { this.setState({ loading: false }) setTimeout(() => { Alert.alert("Information", '\n' + res.Message) }, 300) } else { if(res.success) { this.setState({ loading: false }) this.props.route?.params.onAddNewCard({ userPaymentSourceId: res.response.userPaymentSourceId, referenceNumber: res.response.referenceNumber }, this.state.enableDefaultCard); } else { setTimeout(() => { this.setState({ loading: false }) Alert.alert("Information", '\n' + res.Message); }, 300) } } }, (error) => { this.setState({ loading: false }) setTimeout(() => { Alert.alert("Information", '\n' + error) callback(); }, 300) }) } submitNewAddedCard = () => { if(this.state.cardNumber == null || this.state.cardExpiry == null || this.state.cardCVV == null) { this.setState({ showModal: true }) return } let numberYear = moment(new Date()).format('YYYY').slice(0, 2) //get initial 2 digits of year let cardnumber = this.state.cardNumber.replace(/\s/g, "") let cardExpiry = `${this.state.cardExpiry.split("/")[0]}${numberYear}${this.state.cardExpiry.split("/")[1]}` let cardCvv = this.state.cardCVV let cardZipcode = this.state.cardZipcode if(!cardValidator.number(cardnumber)?.card?.type || cardnumber.length < 16) { Alert.alert("Information", '\n' + `Invalid card number. Please use different card type.`) return } if(!cardValidator.expirationDate(cardExpiry).isValid) { Alert.alert("Information", '\n' + "Invalid expiration date. Please check and try again.") return } if(!cardValidator.cvv(cardCvv).isValid) { Alert.alert("Information", '\n' + "Invalid cvv number. Please check and try again") return } if(!cardValidator.postalCode(cardZipcode).isValid) { Alert.alert("Information", '\n' + "Invalid zipcode number. Please check and try again") return } let cardDetails = { pan: cardnumber, expDate: cardExpiry, cvv: cardCvv, zipcode: cardZipcode } this.setState({ loading: true }) this.addCard(cardDetails, this.state.pubkey, cardValidator.number(cardnumber).card.niceType, onSuccess => { setTimeout(() => { this.props.navigation.navigate('VerificationWebview', {...onSuccess, onSuccessAuthentication:(referenceNumber, callback) => this._onAuthenticationSuccess(referenceNumber, callback)}) this.setState({ loading: false }) }, 500); }, error => { Alert.alert('Information', '\n' + error) this.setState({ loading: false }) }) } onBackConfirmation = () => { Alert.alert( '', 'Are you sure you want to cancel adding card?', [ { text: 'Cancel', style: 'cancel', }, { text: 'OK', onPress: () => this.props.navigation.goBack(), }, ], {cancelable: true}, ); } notEmpty = () => { const { cardNumber, cardExpiry, cardCVV, customerName, cardZipcode } = this.state; if(cardNumber && cardExpiry && cardCVV && customerName && cardZipcode) { return true; } return false } renderWebview = () => { return ( this.onStateChange(webViewState)}/> ) } renderErrorModal = () => { return ( {}} style={styles.centeredView}> <> {'Please Fill in the required fields'} this.setState({ showModal: false })} style={{ width: 80, height: 30, backgroundColor: Theme.colors.primary, alignItems: 'center', justifyContent: 'center', borderRadius: 5 }}> Ok ) } renderCardForm = () => { return ( Card Number this.setState({ focus_number: true })} onBlur={() => this.setState({ focus_number: false })} onChangeText={(value) => this._handlingCardNumber(value)} style={{ flex: 1, color: this.props.app_theme?.theme.colors.text }} /> Name on Card this.setState({ focus_holder: true })} onBlur={() => this.setState({ focus_holder: false })} onChangeText={(value) => this._handlingCustomerName(value)} style={{ flex: 1, color: this.props.app_theme?.theme.colors.text }} /> this.setState({ focus_expiry: true })} onBlur={() => this.setState({ focus_expiry: false })} onChangeText={(value) => this._handlingCardExpiry(value)} style={{ flex: 1, color: this.props.app_theme?.theme.colors.text, marginRight: 3 }} /> this.setState({ focus_cvv: true })} onBlur={() => this.setState({ focus_cvv: false })} onChangeText={(value) => this._handlingCVV(value)} style={{ flex: 1, color: this.props.app_theme?.theme.colors.text, marginLeft: 3 }} /> this.setState({ focus_zipcode: true })} onBlur={() => this.setState({ focus_zipcode: false })} onChangeText={(value) => this._handlingZipCode(value)} style={{ flex: 1, color: this.props.app_theme?.theme.colors.text, marginLeft: 3 }} /> ) } renderSwitch = () => { return ( Set as primary card this.setState({ enableDefaultCard: !this.state.enableDefaultCard })} /> ) } render() { return ( this.onBackConfirmation()} back={true} menu={false} navigation={this.props.navigation} /> {this.renderErrorModal()} {this.renderCardForm()} {this.renderSwitch()} {this.state.verificationUrl != null && this.renderWebview()} Your card will be charged to ensure that it's valid. Charged amount will be automatically refunded. this.submitNewAddedCard()} style={{ height: 50, marginBottom: 16, backgroundColor: this.notEmpty() ? Theme.colors.primary : this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.border : Theme.colors.primary + "15", justifyContent: 'center', alignItems: 'center', borderRadius: 5, marginHorizontal: 35 }}> Save ) } } const mapStateToProps = (state) => { return { userinfo: state.appUserInfoReducer.userinfo, app_theme: state.appThemeReducer.theme } } export default connect(mapStateToProps, null)(PayatpumpPaymentMethodList) const styles = StyleSheet.create({ centeredView: { flex: 1, justifyContent: "center", backgroundColor: '#00000090', }, modalView: { margin: 25, backgroundColor: "white", borderRadius: 15, padding: 20, alignItems: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5 }, cardContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: Theme.colors.gray, height: 40, borderRadius: 5, marginVertical: 10, marginHorizontal: 16 }, expirationCvvContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: Theme.colors.gray, height: 40, borderRadius: 5, marginVertical: 10 } })