razorpay / razorpay-android-sample-app

Sample app demonstrating integration of Razorpay checkout
MIT License
89 stars 90 forks source link

unable to integrate Razorpay in Fragment #210

Closed Mustangodhra closed 3 years ago

Mustangodhra commented 3 years ago

and i am getting error like : Error: onPaymentError probably not implemented in your activity . so , guide me how to solve it.

@52280 Implement the PaymentResultListener or PaymentResultWithDataListener(which I have done in the example) in the parent activity and notify the fragment about the event using a ViewModel See : https://developer.android.com/guide/fragments/communicate#viewmodel

Create a ViewModel called SharedViewModel like:

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Boolean> onSuccess = new MutableLiveData<>();
    private final MutableLiveData<Boolean> onError = new MutableLiveData<>();

    private PaymentError paymentError;
    private PaymentSuccess paymentSuccess;

    public LiveData<Boolean> getOnSuccess() {
        return onSuccess;
    }

    public LiveData<Boolean> getOnError() {
        return onError;
    }

    public void setOnSuccess(Boolean b) {
        onSuccess.setValue(b);
    }

    public void setOnError(Boolean b) {
        onError.setValue(b);
    }

    public PaymentError getPaymentError() {
        return paymentError;
    }

    public void setPaymentError(PaymentError paymentError) {
        this.paymentError = paymentError;
    }

    public PaymentSuccess getPaymentSuccess() {
        return paymentSuccess;
    }

    public void setPaymentSuccess(PaymentSuccess paymentSuccess) {
        this.paymentSuccess = paymentSuccess;
    }
}

Now in your activity do this:

private SharedViewModel sharedViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    ...

    sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);
    sharedViewModel.setOnSuccess(false);
    sharedViewModel.setOnError(false);

    ...
    ...
}

@Override
public void onPaymentSuccess(String razorpayPaymentId, PaymentData paymentData) {
    PaymentSuccess paymentSuccess = new PaymentSuccess(razorpayPaymentId, paymentData);

    sharedViewModel.setPaymentSuccess(paymentSuccess);
    sharedViewModel.setOnSuccess(true);
}

@Override
public void onPaymentError(int code, String description, PaymentData paymentData) {
    PaymentError paymentError = new PaymentError(code, description, paymentData);

    sharedViewModel.setPaymentError(paymentError);
    sharedViewModel.setOnError(true);
}

In the fragment do this without implementing the listener in it:

private SharedViewModel sharedViewModel;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    ..
    ..

    Checkout.preload(getContext());

    sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

    sharedViewModel.getOnSuccess().observe(getViewLifecycleOwner(), onSuccess -> {
        if (onSuccess) {
            PaymentSuccess success = sharedViewModel.getPaymentSuccess();

            onPaymentSuccess(success.getRazorpayPaymentId(), success.getPaymentData());
        }
    });

    sharedViewModel.getOnError().observe(getViewLifecycleOwner(), onError -> {
        if (onError) {
            PaymentError error = sharedViewModel.getPaymentError();

            onPaymentError(error.getCode(), error.getDescription(), error.getPaymentData());
        }
    });

    ..
    ..
}

public void onPaymentSuccess(String razorpayPaymentId, PaymentData paymentData) {
    sharedViewModel.setOnSuccess(false);
    Checkout.clearUserData(getContext());

    // Do something
}

public void onPaymentError(int code, String description, PaymentData paymentData) {
    sharedViewModel.setOnError(false);
    Checkout.clearUserData(getContext());

    // Do something
}

The classes PaymentError and PaymentSuccess are :

public class PaymentSuccess {
    private String razorpayPaymentId;
    private PaymentData paymentData;

    public PaymentSuccess(String razorpayPaymentId, PaymentData paymentData) {
        this.razorpayPaymentId = razorpayPaymentId;
        this.paymentData = paymentData;
    }

    public String getRazorpayPaymentId() {
        return razorpayPaymentId;
    }

    public PaymentData getPaymentData() {
        return paymentData;
    }
}

public class PaymentError {
    private int code;
    private String description;
    private PaymentData paymentData;

    public PaymentError(int code, String description, PaymentData paymentData) {
        this.code = code;
        this.description = description;
        this.paymentData = paymentData;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }

    public PaymentData getPaymentData() {
        return paymentData;
    }
}

I tried this code but i am getting an error which shows:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.saiftechnology.eventpool, PID: 15810 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.saiftechnology.eventpool/com.saiftechnology.eventpool.student.studentAccount}: java.lang.RuntimeException: Cannot create an instance of class com.saiftechnology.eventpool.student.eventDetailsFragment$SharedViewModel at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3311) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3460) at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047) at android.os.Handler.dispatchMessage(Handler.java:107) at android.os.Looper.loop(Looper.java:224) at android.app.ActivityThread.main(ActivityThread.java:7590) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) Caused by: java.lang.RuntimeException: Cannot create an instance of class com.saiftechnology.eventpool.student.eventDetailsFragment$SharedViewModel at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:221) at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278) at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) at com.saiftechnology.eventpool.student.studentAccount.onCreate(studentAccount.java:40) at android.app.Activity.performCreate(Activity.java:7893) at android.app.Activity.performCreate(Activity.java:7880) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3286) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3460)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:224)  at android.app.ActivityThread.main(ActivityThread.java:7590)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)  Caused by: java.lang.InstantiationException: java.lang.Class<com.saiftechnology.eventpool.student.eventDetailsFragment$SharedViewModel> has no zero argument constructor at java.lang.Class.newInstance(Native Method) at androidx.lifecycle.ViewModelProvider$NewInstanceFactory.create(ViewModelProvider.java:219) at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:278)  at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:112)  at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)  at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)  at com.saiftechnology.eventpool.student.studentAccount.onCreate(studentAccount.java:40)  at android.app.Activity.performCreate(Activity.java:7893)  at android.app.Activity.performCreate(Activity.java:7880)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3286)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3460)  at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)  at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)  at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2047)  at android.os.Handler.dispatchMessage(Handler.java:107)  at android.os.Looper.loop(Looper.java:224)  at android.app.ActivityThread.main(ActivityThread.java:7590)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)  I/ology.eventpoo: ProcessProfilingInfo new_methods=2208 is saved saved_to_disk=1 resolve_classes_delay=8000

the code which is pointed in the error (studentAccount.java:40) is: sharedViewModel = new ViewModelProvider(this).get(eventDetailsFragment.SharedViewModel.class);

Appreciate your help.

Originally posted by @Mustangodhra in https://github.com/razorpay/razorpay-android-sample-app/issues/9#issuecomment-800784522

vivekshindhe commented 3 years ago

@Mustangodhra Two points,

Let us know if you need any more clarification on the same.

sumedht commented 3 years ago

@Mustangodhra Closing this issue as there is no further communication on this. U can always re-open if u still facing this issue.

rahulsharma0657 commented 2 years ago

You can try to implement the razor pay in activity and then get the call back in the fragment.