iamraphson / react-paystack

ReactJS library for implementing paystack payment gateway
https://www.npmjs.com/package/react-paystack
MIT License
445 stars 159 forks source link

Calling initialize Payment after axios response #49

Open deLTreeTech opened 2 years ago

deLTreeTech commented 2 years ago

I have a need to first get reference from axios call, set the reference in config then make call to make payment on axios response. Is there anyway I can use this library to achieve this. Thanks

Irene-24 commented 2 years ago

@deLTreeTech , were you able to solve this?

deLTreeTech commented 2 years ago

Yes. I did this initially:

const initialConfig = { reference: null, email: userEmail, amount: 0, publicKey: REACT_APP_PAYSTACK_KEY, };

const [config, setConfig] = useState(initialConfig);

let initializePayment = usePaystackPayment(config);

Then when payment button is clicked, I set config state:

setConfig({ ...config, reference: response.data.data.cartReference, amount: cartTotalPrice() * 100, });

Irene-24 commented 2 years ago

Yes. I did this initially:

const initialConfig = { reference: null, email: userEmail, amount: 0, publicKey: REACT_APP_PAYSTACK_KEY, };

const [config, setConfig] = useState(initialConfig);

let initializePayment = usePaystackPayment(config);

Then when payment button is clicked, I set config state:

setConfig({ ...config, reference: response.data.data.cartReference, amount: cartTotalPrice() * 100, });

@deLTreeTech Thanks, I'll try it out

kbuika commented 1 year ago

Yes. I did this initially:

const initialConfig = { reference: null, email: userEmail, amount: 0, publicKey: REACT_APP_PAYSTACK_KEY, };

const [config, setConfig] = useState(initialConfig);

let initializePayment = usePaystackPayment(config);

Then when payment button is clicked, I set config state:

setConfig({ ...config, reference: response.data.data.cartReference, amount: cartTotalPrice() * 100, });

does this actually work? Considering the asynchronous nature of state updates.

deLTreeTech commented 1 year ago

Yes. I did this initially: const initialConfig = { reference: null, email: userEmail, amount: 0, publicKey: REACT_APP_PAYSTACK_KEY, }; const [config, setConfig] = useState(initialConfig); let initializePayment = usePaystackPayment(config); Then when payment button is clicked, I set config state: setConfig({ ...config, reference: response.data.data.cartReference, amount: cartTotalPrice() * 100, });

does this actually work? Considering the asynchronous nature of state updates.

Yes. It does

kbuika commented 1 year ago

@deLTreeTech Okay, nice. That did not work for me. I had to create a custom hook and return a method that would allow me to update the config and trigger a payment. I haven't had any side-effect with it

import { useEffect, useState } from 'react';
import { usePaystackPayment } from 'react-paystack';
import { errorToast } from '@/lib/utils';
import { PaystackProps } from "react-paystack/dist/types";
import { callback } from '@/types';

interface CustomPaymentProps {
    config: PaystackProps,
    onSuccess: callback,
    onClose: () => void
}

// TODO: Post-mortem this solution
const useCustomPaystackPayment = ({config, onSuccess, onClose}: CustomPaymentProps) => {
  const [paymentReference, setPaymentReference] = useState(config.reference);

  const initializePayment = usePaystackPayment({
    ...config,
    reference: paymentReference,
  });

  useEffect(() => {
    if (paymentReference) {
      initializePayment(onSuccess, onClose);
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [paymentReference]);

  const handlePayment = (newReference: string) => {
    if (newReference) {
      setPaymentReference(newReference);
    } else {
      errorToast('Invalid payment reference.');
    }
  };

  return {
    handlePayment,
  };
};

export default useCustomPaystackPayment;