import * as React from 'react'; import { View, Text, TouchableOpacity, Alert, Platform, Image } from 'react-native'; import { Image as NBImage, Button, ScrollView } from 'native-base'; import { TotalAmount, Buyer, Item, Ref, CheckOut } from '../../components/paymaya/checkout'; import { saveUserInfo } from "../../redux/actions/AppUserInfoActions"; import { Input } from 'react-native-elements'; import { connect } from "react-redux"; import Icon from '../../components/icons.js'; import CustomSafeArea from '../../components/safeArea.component.js'; import NetInfo from '../../components/netstatus'; import CustomHeader from '../../components/header.js'; import Theme from '../../components/theme.style.js'; import Assets from '../../components/assets.manager.js'; import Elements from '../../components/elements.js'; import REQUEST from '../../components/api'; import DB from '../../components/storage/'; import TokenizationForm from './form'; import Tokenization from '../../components/paymaya/tokenization' import moment from 'moment'; // const PAYMENT_ENV = "SANDBOX" // const PAYMENT_ENV = "PRODUCTION" class TopUp extends React.Component { constructor(props) { super(props) this.current = "" } state = { connected: false, isCardFormVisible: false, loading: false, popup: false, Task: "", DisplayAmount: "", amount: 0, focused: false, checkoutResult: "", userProfile: null, session: null, topupCount: 0, merchant: {}, creditcards: [], activeIndex: 0, isKeyboardActive: false, tokenizationFormCount: 0, transactionType: null } componentDidMount() { NetInfo.netstatus(isConnected => { if(isConnected) { this.init() } else { Elements.nointernet2() } }) } componentWillUnmount() { } init = async () => { let user = await DB.profile() const session = await DB.session() this.setState({ connected: true, loading: true, userProfile: user, session: session }) if(user.data.civilstatus_code == "0" || user.data.gender_code == "0") { Alert.alert("Information", "Update your Profile first to use this feature.", [{text: "OK", onPress: () => this.props.navigation.goBack()}]) return } this.countTransactions() this.getMerchant() } countTransactions = async () => { const SESSION = await DB.session() await REQUEST("transactions", "get", { Authorization: SESSION.token, card_number: SESSION.user.card_number }, {}, {}, (res) => { console.log(res) let count = 0 if(res.data.length > 0){ for(var x=0;x= 5){ this.setState({ loading: false }) Platform.OS == 'ios' ? setTimeout(() => { Alert.alert("Top Up", "\nYou have reached your maximum top up for this day.") }, 700) : Alert.alert("Top Up", "\nYou have reached your maximum top up for this day.") } }, (error) => { this.setState({ loading: false }) console.log(error) }) } handleDelete = (id, token, uuid) => { Alert.alert( "Delete Payment Card", "Are you sure you want to delete this card?", [ { text: "NO", style: "cancel" }, { text: "YES", onPress: () => { this.setState({ loading: true }) Tokenization.initRemove(id, token, uuid).then((res) => { this.setState({ loading: false }) if(res.result == 'OK'){ setTimeout(() => { Alert.alert("Deleted Successfully", "\nYour credit card has successfully deleted.", [{text: "OK", onPress: async () => { this.init() let creditcards = this.state.creditcards.filter(function(item){ return item.uuid != uuid }).map(function(item){ return item }) this.setState({ creditcards: creditcards }) }}]) }, 300) } }) } }, ] ) } getMerchant = async () => { const USER_PROFILE = await DB.profile() const SESSION = await DB.session() await REQUEST("paymaya_tokens", "get", {'Authorization': SESSION.token}, {noID: true, value: USER_PROFILE.data.card_number}, {}, async (res) => { if(res.data && res.data.cards){ this.setState({ merchant: res.data, activeIndex: 0 }) for(var x=0;x { this.setState({ loading: false }) console.log(error) }) } moneyFormat = (price, sign = 'PHP ') => { const pieces = parseFloat(price).toFixed(2).split('') let ii = pieces.length - 3 while ((ii-=3) > 0) { pieces.splice(ii, 0, ',') } return sign + pieces.join('') } setamount = (value) => { this.setState({ DisplayAmount: this.moneyFormat(value).toString(), amount: value }) } onAmountChange = (value) => { if(value != this.current){ let parsed = parseFloat(this.clean(value)) if(parsed > 1000000) return false let formatted = this.formatCurrency(parsed) this.current = formatted this.setState({ DisplayAmount: formatted, amount: parseFloat(parsed/100) }) } } clean = (str) => { return str.replace("PHP ", "").replace(".", "").replace(",", "").toString() } formatCurrency = (val) => { let fv = isNaN(val) ? (0).toFixed(2) : parseFloat(val / 100).toFixed(2) return val.length == 6 ? "PHP " + fv.substr(0, 1) + "," + fv.substr(2, fv.length) : "PHP " + fv } validate = () => { if(this.state.amount < 100 || this.state.amount > 10000){ Alert.alert("Invalid top up amount", "\nPlease enter value between 100 - 10,000 pesos only.\n") return false } return true } onReload = (res, msg) => { console.log("onBack", res, msg) } updateTopup = (transactionId, amount, onSuccess, onError) => { REQUEST('topup_transaction_entry', 'post', { Authorization: this.state.session.token }, {}, { amount: amount, paymaya_tranx_id: transactionId }, (res) => onSuccess(res), (error) => onError(error)) } initCheckout = async () => { if(!this.validate()) return false if(this.state.creditcards.length > 0){ let mct = this.state.creditcards[this.state.activeIndex] Alert.alert("Confirm Top Up", "\nYour card number will be used to pay for "+parseFloat(this.state.amount).toFixed(2)+" points.", [ {text: "NO",style: "cancel"}, {text: "YES", onPress: async () => { let payout = await Tokenization.initNewPayout(mct.cardTokenId, this.state.amount); if(payout.status == "success") { this.setState({ loading: true }) this.updateTopup(payout.id, this.state.amount, onSuccess => { this.setState({ loading: false }) let data = { amount: this.state.amount, transactionId: payout.id, data: {redirectUrl: payout.verificationUrl, card_number: mct.maskedPan, type: 'create' }, onBack: (res, msg) => alert(msg) } this.props.navigation.navigate('CheckOut', data) }, onError => { setTimeout(() => { Alert.alert("Top Up", `\n${onError.error}`) }, 700) }) } else if(payout.status == "failed"){ this.setState({ loading: false }) if(payout.parameters.length > 0) { setTimeout(() => { Alert.alert("Top Up", `\n${payout.parameters[0]?.description}`) }, 700) } else { Platform.OS == 'ios' ? setTimeout(() => { Alert.alert("Top Up", "\nFailed to add new card.") }, 300) : Alert.alert("Top Up", "\nFailed to add new card.") } } } } ]) } else { this.setState({ isCardFormVisible: true }) } } initAddCard = async () => { this.setState({ isCardFormVisible: true, tokenizationFormCount: this.state.tokenizationFormCount + 1, transactionType: "add" }) } getDisplayCard = (type) => { if(!type) return else if(type == "visa") return Assets.icons.stpvisa else if(type == "master-card") return Assets.icons.stpmastercard else if(type == "jcb") return Assets.icons.stpjcb else return Assets.icons.stpunknown } renderCardform = () => { return ( 0 ? this.state.merchant.customer_id : ''} amount={this.state.amount} onDone={() => { this.init() console.log("onDone") }} onBack={(res, msg) => { this.onReload(res, msg) }} onGoBack={() => { this.setState({ isCardFormVisible: false }) console.log("onGoBack") }} onSuccess={data => { console.log("onSucces", data) this.props.navigation.navigate('CheckOut', data) }} /> ) } render() { console.log("The Credit Cards: " + JSON.stringify(this.state.creditcards)); if(!this.state.connected){ return ( this.init()} /> ) } return ( {this.state.isCardFormVisible && this.renderCardform()} Select Top Up Value Points this.setamount(100)} style={{flex: 1, margin: 10, padding: 10, borderRadius: 10, borderColor: Theme.colors.primary, borderWidth: 2}}> 100 this.setamount(500)} style={{flex: 1, margin: 10, padding: 10, borderRadius: 10, borderColor: Theme.colors.primary, borderWidth: 2}}> 500 this.setamount(1000)} style={{flex: 1, margin: 10, padding: 10, borderRadius: 10, borderColor: Theme.colors.primary, borderWidth: 2}}> 1000 this.setamount(5000)} style={{flex: 1, margin: 10, padding: 10, borderRadius: 10, borderColor: Theme.colors.primary, borderWidth: 2}}> 5000 Or Enter Desired Value (maximum of 10,000 points) this.setState({ focused: true })} onChangeText={(value) => this.onAmountChange(value)} containerStyle={{padding: 0}} inputContainerStyle={{padding: 0, borderBottomWidth: this.state.focused ? 1.75 : 1, borderColor: this.state.focused ? Theme.colors.accent : "gray" }} inputStyle={{padding: 0, fontFamily: 'Arial', fontSize: 16, color: this.props.app_theme?.theme.colors.text }} /> Note: Top Up to a maximum of five(5) times per day. Payment Method { this.state.creditcards.length > 0 && {this.state.creditcards[this.state.activeIndex]?.cardType.toString().toUpperCase()} {this.state.creditcards[this.state.activeIndex]?.maskedPan} **** **** **** {this.state.creditcards[this.state.activeIndex]?.maskedPan} } { this.state.creditcards && this.state.creditcards.length === 0 && 0000 0000 0000 0000 } { this.state.creditcards.length <= 5 && ( this.initAddCard()} style={{flexDirection: 'row', alignItems: 'center', padding: 15, borderBottomWidth: 0.5, borderColor: 'lightgray'}}> Add New Card ) } { this.state.creditcards.length > 0 && this.state.creditcards.map((card, index) => { return ( { Alert.alert("Select Card", "**** **** **** " + card?.maskedPan + " is selected.", [{text: "OK"}]) this.setState({ activeIndex: index }); }} style={{flexDirection: 'row', flex: 1, alignItems: 'center'}}> {card?.cardType.toString().toUpperCase()} **** **** **** {card?.maskedPan} ) }) } {this.state.topupCount >= 5 ? null : 0 ? false : true} style={{justifyContent: 'center', marginHorizontal: 15, paddingVertical: 15, borderRadius: 10, backgroundColor: this.state.creditcards.length > 0 ? Theme.colors.primary : this.props.app_theme?.theme.dark ? this.props.app_theme?.theme.colors.border : Theme.colors.primary + "15", marginBottom: 16}} onPress={() => this.initCheckout()}> Next } ) } } const mapStateToProps = (state) => { return { userinfo: state.appUserInfoReducer.userinfo, app_theme: state.appThemeReducer.theme } } const mapDispatchToProps = { saveUserInfo } export default connect(mapStateToProps, mapDispatchToProps)(TopUp);