UNPKG

react-native-paysofter

Version:

This is a React Native package for integrating Paysofter payment gateway into your React Native application.

314 lines (295 loc) 8.83 kB
// VerifyAccountFundOtp.js import React, { useState, useEffect, useCallback } from "react"; import { View, Text, TextInput, Button, StyleSheet, TouchableOpacity, } from "react-native"; import { Card } from "react-native-paper"; import AsyncStorage from "@react-native-async-storage/async-storage"; import Message from "./Message"; import MessageFixed from "./MessageFixed"; import Loader from "./Loader"; import { PAYSOFTER_API_URL } from "./config/apiConfig"; import axios from "axios"; import SuccessScreen from "./SuccessScreen"; const VerifyAccountFundOtp = ({ amount, email, currency, paysofterPublicKey, qty, productName, referenceId, formattedPayerEmail, onSuccess, onClose, }) => { const [otp, setOtp] = useState(""); const [resendDisabled, setResendDisabled] = useState(false); const [resendLoading, setResendLoading] = useState(false); const [resendMessage, setResendMessage] = useState(""); const [countdown, setCountdown] = useState(60); const [showSuccessMessage, setShowSuccessMessage] = useState(false); const [hasHandledSuccess, setHasHandledSuccess] = useState(false); const [showSuccessScreen, setShowSuccessScreen] = useState(false); const [paymentSuccess, setPaymentSuccess] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [sendOtpData, setSendOtpData] = useState(null); const createdAt = new Date().toLocaleString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: true, timeZoneName: "short", }); const paymentMethod = "Paysofter Account Fund"; useEffect(() => { const fetchSendOtpData = async () => { const data = await AsyncStorage.getItem("debitAccountData"); setSendOtpData(JSON.parse(data)); }; fetchSendOtpData(); }, []); const otpData = { otp: otp, account_id: sendOtpData?.account_id, amount: sendOtpData?.amount, // amount: amount, currency: currency, public_api_key: paysofterPublicKey, }; const paysofterPaymentData = { buyer_email: sendOtpData?.email, amount: sendOtpData?.amount, currency: sendOtpData?.currency, account_id: sendOtpData?.account_id, public_api_key: sendOtpData?.public_api_key, // buyer_email: email, // amount: amount, // currency: currency, // public_api_key: paysofterPublicKey, qty: qty, product_name: productName, reference_id: referenceId, created_at: createdAt, payment_method: paymentMethod, }; // console.log('paysofterPaymentData:', paysofterPaymentData) const debitAccountData = { account_id: sendOtpData?.account_id, security_code: sendOtpData?.security_code, amount: sendOtpData?.amount, // amount: amount, currency: currency, public_api_key: paysofterPublicKey, }; const handleVerifyEmailOtp = async () => { setLoading(true); setError(null); try { await axios.post(`${PAYSOFTER_API_URL}/api/verify-otp/`, otpData); handleCreatePaysofterPayment(); } catch (error) { setError( error.response && error.response.data.detail ? error.response.data.detail : error.message ); } setLoading(false); }; const handleCreatePaysofterPayment = async () => { setLoading(true); setError(null); try { await axios.post( `${PAYSOFTER_API_URL}/api/initiate-transaction/`, paysofterPaymentData ); setPaymentSuccess(true); setShowSuccessMessage(true); setHasHandledSuccess(true); handleOnSuccess(); setTimeout(() => { // handleOnClose(); setShowSuccessMessage(false); setShowSuccessScreen(true); }, 3000); } catch (error) { setError( error.response && error.response.data.detail ? error.response.data.detail : error.message ); } setLoading(false); }; const handleResendEmailOtp = async () => { setResendLoading(true); setResendMessage(""); try { await axios.post( `${PAYSOFTER_API_URL}/api/send-debit-fund-account-otp/`, debitAccountData ); setResendMessage(`OTP resent to ${formattedPayerEmail} successfully.`); setResendDisabled(true); } catch (error) { setResendMessage("Error resending OTP. Please try again."); } setResendLoading(false); }; useEffect(() => { let timer; if (countdown > 0 && resendDisabled) { timer = setTimeout(() => setCountdown(countdown - 1), 1000); } else if (countdown === 0 && resendDisabled) { setResendDisabled(false); } else if (!resendDisabled) { setCountdown(60); } return () => { clearTimeout(timer); }; }, [countdown, resendDisabled]); const handleOnSuccess = useCallback(() => { onSuccess(); }, [onSuccess]); // const handleOnClose = useCallback(() => { // onClose(); // }, [onClose]); useEffect(() => { if (paymentSuccess && !hasHandledSuccess) { setHasHandledSuccess(true); setShowSuccessMessage(true); // handleOnSuccess(); setTimeout(() => { setShowSuccessScreen(true); setShowSuccessMessage(false); AsyncStorage.removeItem("debitAccountData"); }, 3000); } }, [paymentSuccess, hasHandledSuccess]); return ( <View style={styles.container}> {showSuccessScreen ? ( <SuccessScreen /> ) : ( <Card style={styles.card}> <Card.Content> <Text style={styles.header}>Verify OTP</Text> {showSuccessMessage && ( <Message variant="success">Payment made successfully!</Message> )} {loading && <Loader />} {error && <Message variant="danger">{error}</Message>} {resendMessage && ( <Message variant={resendLoading ? "info" : "success"}> {resendMessage} </Message> )} <TextInput style={styles.input} value={otp} onChangeText={(text) => setOtp(text)} placeholder="Enter OTP" keyboardType="numeric" /> <Button onPress={handleVerifyEmailOtp} title="Verify OTP" disabled={otp === "" || loading || showSuccessMessage} color="#28a745" /> <Text style={styles.otpInfo}> OTP has been sent to email: {formattedPayerEmail} for Paysofter Account ID: {sendOtpData?.account_id} and expires in 10 minutes. It might take a few seconds to deliver. </Text> <TouchableOpacity onPress={handleResendEmailOtp} disabled={resendDisabled || resendLoading} > <Text style={styles.resendText}> {resendLoading ? "Resending OTP..." : resendDisabled ? `Resend OTP (${countdown}sec)` : "Resend OTP"} </Text> </TouchableOpacity> <View style={styles.errorContainer}> {error && <MessageFixed variant="danger">{error}</MessageFixed>} </View> </Card.Content> </Card> )} </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, padding: 20, alignItems: "center", }, header: { fontSize: 24, fontWeight: "bold", marginVertical: 20, }, input: { height: 40, borderColor: "#ccc", borderWidth: 1, borderRadius: 5, padding: 10, width: "100%", marginBottom: 20, }, otpInfo: { textAlign: "center", marginVertical: 20, }, resendText: { color: "#007bff", textAlign: "center", marginTop: 20, }, errorContainer: { padding: 10, }, roundedPrimaryBtn: { backgroundColor: "#007bff", color: "#fff", padding: 10, borderRadius: 25, justifyContent: "center", alignItems: "center", textAlign: "center", }, roundedDisabledBtn: { backgroundColor: "#d3d3d3", color: "#fff", padding: 10, borderRadius: 25, justifyContent: "center", alignItems: "center", textAlign: "center", }, btnText: { color: "#fff", fontSize: 14, fontWeight: "bold", }, }); export default VerifyAccountFundOtp;