import * as React from 'react'; import { connect } from "react-redux"; import { Divider } from 'react-native-elements' import { TouchableOpacity, View, Text, Alert, ScrollView, Image, Modal, StyleSheet, BackHandler } from 'react-native'; import { returnIcon } from '../../utils/card.js'; import { saveUserInfo } from "../../redux/actions/AppUserInfoActions"; import NetInfoCommunity from '@react-native-community/netinfo'; import CustomHeader from '../../components/header.js'; import NetInfo from "../../components/netstatus"; import Assets from '../../components/assets.manager.js'; import Theme from '../../components/theme.style.js'; import REQUEST_POST_PAY from '../../components/api/postpayapi'; import DB from '../../components/storage'; import Elements from '../../components/elements'; import CustomSafeArea from '../../components/safeArea.component'; import axios from 'axios'; class PayatpumpStationTransactionDetails extends React.Component { constructor(props) { super(props) this.cancelToken1 = axios.CancelToken.source() } state = { loading: false, session: null, card_number: null, selectedPoints: null, selectedPaymentCard: null, claimId: null, data: [], storeName: null, showModal: false, showRetryModal: false, initiated: false, totalPrice: 3000, message: "Your Payment is being processed.", title: "Payment Processing", res: null, res2: null } componentDidMount() { this.init(); this.netListener = NetInfoCommunity.addEventListener((response => { if(!response.isConnected && !this.state.res) { this.cancelToken1.cancel(); this.cancelToken1 = axios.CancelToken.source(); Elements.nointernet2(); } else if(!response.isConnected && this.state.res) { if(this.timer) clearTimeout(this.timer); this.setState({ message: "Your Payment is being processed.", title: "Payment Processing", loading: false }) Elements.nointernet2(); } else if(!response.isConnected && this.state.res && this.state.res3) { if(this.timer) clearTimeout(this.timer); this.setState({ message: "Please wait while we process your transaction details.", title: "Payment Details", loading: false }) Elements.nointernet2(); } })) } componentWillUnmount() { this.netListener(); } init = async () => { let session = await DB.session() let user_profile = await DB.profile() let selectedCard = await DB.get("pumpPaymentCards"); this.setState({ card_number: user_profile.data.card_number, session: session, claimId: this.props.route.params.response.claimId, data: this.props.route.params.response.saleItems, storeName: this.props.route.params.storeName, selectedPumpNumber: this.props.route.params.selectedPump, selectedPaymentCard: JSON.parse(selectedCard) }) } onBackHandler = (type) => { if (type === "disable") return BackHandler.addEventListener("hardwareBackPress", this.onBack); else if (type === "enable") return BackHandler.removeEventListener("hardwareBackPress", this.onBack) } onBack = () => { return true } onSelectedPointsAmount = (point_amount) => { this.setState({ selectedPoints: point_amount }) } onSelectedPaymentCard = (payment_card) => { this.setState({ selectedPaymentCard: payment_card }) } getTransactionDetails = async (claimId, fundingProviderName, userPaymentSourceId, onSuccess, onError) => { if(this.state.initiated) { onError({customError: "Unable to get status of the transaction.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }]}) return; } this.setState({ initiated: true }) let cardNumber = this.props.userinfo.data.card_number; if (claimId == null) { Alert.alert("Information", '\n' + "No transaction id exist.") return } let body = { claim_id: claimId, partner_trans_id: "93931", walletRequests: [{ fundingProviderName: fundingProviderName, fundingPayload: { userPaymentSourceId: userPaymentSourceId } }, { fundingProviderName: "loyalty_points", fundingPayload: { "paymentToken": cardNumber, "points": 0 } }] } REQUEST_POST_PAY('postpay', 'post', {}, {}, body, async (res) => { if (res.status) { // this.setState({res: res}) // this.recheckStatus(res, onSuccess, onError) } else { onError(res) } }, (error) => { onError(error) }, this.cancelToken1) } recheckStatus = async (res, onSuccess, onError) => { this.setState({ title: "Payment Details", message: "Please wait while we process your transaction details." }) const USER_PROFILE = await DB.profile(); REQUEST_POST_PAY('getTransactionStatusDetails', "get", { token: USER_PROFILE.data.auth_p97, language: 'en-US' }, { transactionID: res.response.transaction_id }, {}, res2 => { if(res2.response && res2.response.status === "Finished") { this.setState({ res2: res2 }) return this.requestTransactionDetails(res, res2, onSuccess, onError); } else if(res2.response && res2.response.status === "Timeout") { return onError({ customError: "Transaction timeout. Please try again.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "Cancelled") { return onError({ customError: "Cancelled transaction.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "ConnectivityIssue") { return onError({ customError: "Connection timeout. Please try again.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "VelocityTrigger") { return onError({ customError: "Unable to proceed with the transaction. Please contact our hotline.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "Cancelled") { return onError({ customError: "Cancelled transaction.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "Failed") { return onError({ customError: "Failed to initiate transaction. Please try again.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "AuthFailed") { return onError({ customError: "Failed to initiate transaction. Please try again.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "FinalizeFailed") { return onError({ customError: "Unable to process your payment at this time. Please pay in-store.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else if(res2.response && res2.response.status === "ProcessingError") { return onError({ customError: "Processing failed. Please pay in-store.", buttons: [{ text: 'Ok', onPress: () => { this.props.navigation.reset({ index: 0, routes: [{name: 'Main'}] }) } }] }) } else { this.timer = setTimeout(() => { this.recheckStatus(res, onSuccess, onError) }, 5000) } }, (error) => { onError(error); }) } requestTransactionDetails = async (res, res2, onSuccess, onError) => { const USER_PROFILE = await DB.profile(); REQUEST_POST_PAY("getTransactionDetails/" + res2.response.transactionId, "get", { token: USER_PROFILE.data.auth_p97, language: 'en-US' }, {}, {}, res3 => { if (res3.success) { onSuccess({ res: res, onSuccess: res2, newDetails: res3 }) } else { setTimeout(() => { this.requestTransactionDetails(res, res2, onSuccess, onError); }, 5000); } }, err => { onError(err); }) } submitPayment = () => { this.onBackHandler("disable"); this.setState({ showModal: false }) NetInfo.netstatus((response) => { if(!response) { Elements.nointernet2(); this.onBackHandler("enable"); } else { this.setState({ loading: true }) this.getTransactionDetails(this.state.claimId, "p97token", this.state.selectedPaymentCard.userPaymentSourceId, this.onSuccess, this.onError) } }) } onSuccess = (onSuccess) => { if (onSuccess.res.success) { let payment = { totalPayment: this.state.data[0]?.originalAmount.amount, cardPayment: this.state.data[0].originalAmount.amount, transactionId: onSuccess.res.response.transaction_id, storeName: this.state.storeName }; this.props.saveUserInfo({ token: this.state.session.token, card_number: this.state.session.user.card_number }).then(profile => { DB.updateProfile(profile, () => { this.onBackHandler("enable"); this.setState({ loading: false }); this.props.navigation.navigate('PayatpumpPaymentSuccess', { transactionData: payment, transactionDetails: onSuccess.onSuccess, newDetails: onSuccess.newDetails }); }, () => { }) }) } else { this.onError(); } } onError = (error) => { // this.setState({ loading: false }); // if(error.buttons) { // Alert.alert("Information", '\n' + (error?.customError || "Failed to initiate transaction. Try again."), error.buttons); // } else { // if(error?.toJSON().message !== 'Network Error') { // Alert.alert("Information", '\n' + (error?.customError || "Failed to initiate transaction. Try again.")); // } // } } renderModal = () => { return ( { }} style={styles.centeredView}> {this.state.selectedPoints == null && this.state.selectedPaymentCard == null ? <> {'Please select payment method'} this.setState({ showModal: false })} style={{ width: 80, height: 30, backgroundColor: Theme.colors.primary, alignItems: 'center', justifyContent: 'center' }}> OK : {`You are about to pay \n ${"\u20B1"} ${Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)}`} {`If your transaction is valid for\ndiscount, it will be reflected after final payment.`} { this.setState({ showModal: false }) }}> Cancel this.submitPayment()}> Continue } ) } renderRetryModal = () => { return ( { }} style={styles.centeredView}> {`You have a pending transaction\ndo you want to proceed?`} { this.setState({ showRetryModal: false }) }}> No { this.setState({ showRetryModal: false, loading: true }) this.recheckStatus(this.state.res, this.onSuccess, this.onError) }}> Yes ) } transactionTable = () => { const renderItem = () => { return this.state.data?.map((item, index) => { return ( {item.description} {item.quantity} {"\u20B1"}{Theme.formatter.CRNCY(item.originalAmount.unitPrice)} {"\u20B1"}{Theme.formatter.CRNCY(item.originalAmount.amount)} ) }) } return ( Product Qty Price Total {renderItem()} ) } onBackConfirmation = () => { Alert.alert( '', 'Do you want to cancel this transaction?', [ { text: 'Cancel', style: 'cancel', }, { text: 'OK', onPress: () => this.props.navigation.goBack(), }, ], { cancelable: true }, ); } renderSelectedCard = () => { return ( { this.state.selectedPaymentCard ? <> this.props.navigation.navigate('PayatpumpPaymentList', { onSelectedPaymentCard: (payment_card) => this.onSelectedPaymentCard(payment_card), storeId: this.props.route?.params.storeId })} > Change {this.state.selectedPaymentCard.lastFour} : this.props.navigation.navigate('PayatpumpPaymentList', { onSelectedPaymentCard: (payment_card) => this.onSelectedPaymentCard(payment_card), storeId: this.props.route?.params.storeId })} > Add Card } {"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)} ) } render() { return ( {this.state.storeName} {'\n'}Pump No. {this.state.selectedPumpNumber} } height={75} onBackPress={() => this.onBackConfirmation()} back={true} customTitleStyle={{ fontWeight: 'bold' }} customLeftContainerStyle={{ justifyContent: 'flex-start' }} menu={false} navigation={this.props.navigation} /> {this.renderModal()} {this.renderRetryModal()} {this.transactionTable()} Payment Method Total {"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)} {this.renderSelectedCard()} Review the details before proceeding. { if(this.state.res) { this.setState({ showRetryModal: true }) } else { this.setState({ showModal: true }) } }} style={{ height: 50, backgroundColor: Theme.colors.primary, alignItems: 'center', justifyContent: 'center', borderRadius: 10, marginHorizontal: 16 }}> Pay {"\u20B1"} {Theme.formatter.CRNCY(this.state.data[0]?.originalAmount.amount || 0.0)} ); } } const mapStateToProps = (state) => { return { app_theme: state.appThemeReducer.theme, userinfo: state.appUserInfoReducer.userinfo } } const mapDispatchToProps = { saveUserInfo } export default connect(mapStateToProps, mapDispatchToProps)(PayatpumpStationTransactionDetails) const styles = StyleSheet.create({ centeredView: { flex: 1, justifyContent: "center", backgroundColor: '#00000090', }, modalView: { margin: 25, backgroundColor: "white", padding: 20, alignItems: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.25, shadowRadius: 4, elevation: 5 }, })