import * as React from 'react'; import * as UTILS from './utils'; import { connect } from "react-redux"; import { TouchableOpacity, View, Text, Image, Switch, StyleSheet, Modal, Alert, TextInput, Keyboard } from 'react-native'; import { returnIcon } from '../../utils/card'; import { ENV } from '../../components/environment'; import REQUEST from '../../components/api'; import moment from 'moment'; import cardValidator from 'card-validator'; import CustomHeader from '../../components/header.js'; import Theme from '../../components/theme.style.js'; import DB from '../../components/storage/'; import Elements from '../../components/elements.js'; import Assets from '../../components/assets.manager.js'; import Tokenization from '../../components/paymaya/tokenization'; import CustomSafeArea from '../../components/safeArea.component'; class TopupPaymentMethod extends React.Component { constructor(props) { super(props) } state = { cardNumber: null, cardExpiry: null, cardCVV: null, customerName: `${this.props.userinfo.data.firstname} ${this.props.userinfo.data.lastname}`, focus_number: false, focus_holder: false, focus_expiry: false, focus_cvv: false, enableDefaultCard: false, showModal: false, pubkey: null, verificationUrl: null, cardDetails: null, loading: false } addCard = async () => { this.setState({ loading: true }) const USER_PROFILE = await DB.profile(); const SESSION = await DB.session(); let splitedExpiry = this.state.cardExpiry.split("/"); const newCardNumber = this.state.cardNumber.replace(/ /g, "").toString(); const dataToSend = { number: newCardNumber, expmonth: splitedExpiry[0], expyear: moment().year().toString().slice(0, -2) + splitedExpiry[1], cvv: this.state.cardCVV, is_default: this.state.enableDefaultCard, } console.log(dataToSend) await REQUEST("paymaya_tokens", "get", {'Authorization': SESSION.token}, {noID: false, value: USER_PROFILE.data.card_number}, {}, async (res) => { console.log(this.props.route?.params.merchant.customer_id); if(res.status === 1 && res.data) { // const checker = res.data?.cards?.find(card => newCardNumber.includes(card.first6) && newCardNumber.includes(card.last4)); // if(!checker) { if(this.props.route?.params.merchant.customer_id) dataToSend.customer_id = this.props.route?.params.merchant.customer_id; await REQUEST("paymaya_tokens", "post", {'Authorization': SESSION.token}, {}, dataToSend, (result) => { console.log(dataToSend); if(result.status === 1 && result.data) { this.props.navigation.navigate('CheckOut', { data: {redirectUrl: result.data.verificationUrl, card_number: result.data.card_number, type: 'add'}, onBack: () => { this.props.route?.params.onAddNewCard(result.data); this.props.navigation.goBack(); } }); } else { console.log(result) this.setState({ loading: false }) } }, (err) => {}, "Card", "Add") // } // else { // Alert.alert("Warning", '\n' + "Card number already exist.") // this.setState({ loading: false }) // } } else { await REQUEST("paymaya_tokens", "post", {'Authorization': SESSION.token}, {}, dataToSend, (result) => { console.log(dataToSend); if(result.status === 1 && result.data) { this.props.navigation.navigate('CheckOut', { data: {redirectUrl: result.data.verificationUrl, card_number: result.data.card_number, type: 'add'}, onBack: () => { this.props.route?.params.onAddNewCard(result.data); this.props.navigation.goBack(); } }); } else { console.log(result) // Alert.alert("Warning", '\n' + "Card number already exist.") this.setState({ loading: false }) } }, (err) => {}, "Card", "Add") } this.setState({ loading: false }) }, (error) => { console.log(error) this.setState({ loading: false }) this.onError(error); }, "Funding", "Fetch") } onError = (err) => { if(err.toJSON().message !== 'Network Error') { Alert.alert("Information", `\n${err.message}`); } else { Elements.nointernet2() } this.setState({ loading: false }) } _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 { this.setState({ customerName: name }) } _handlingCardExpiry = (number) => { 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 }); } submitNewAddedCard = () => { if(this.state.cardNumber == null || this.state.cardExpiry == null || this.state.cardCVV == null) { this.setState({ showModal: true }) return } let numberYear = moment(Theme.platform === "android" ? Date() : 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 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 } this.setState({ loading: true }); this.addCard(); } notEmpty = () => { const { cardNumber, cardExpiry, cardCVV, customerName } = this.state; if(cardNumber && cardExpiry && cardCVV && customerName) { return true; } return 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}, ); } onSubmitEditing = () => { Keyboard.dismiss(); if(this.notEmpty()) return this.submitNewAddedCard(); } 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 ( Enroll Your Payment Card 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 }} /> ) } 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()} 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 { app_theme: state.appThemeReducer.theme, userinfo: state.appUserInfoReducer.userinfo } } export default connect(mapStateToProps, null)(TopupPaymentMethod) 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, marginBottom: 10, marginHorizontal: 16 }, expirationCvvContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', borderBottomWidth: 1, borderBottomColor: Theme.colors.gray, height: 40, borderRadius: 5, marginVertical: 10 } })