node.jsdartsocket.iopaypal-rest-sdkpaypal-webhooks

How to redirect to the home page after a successful PayPal webhook payment in Flutter?


I'm working on a Flutter app that requires redirecting the user to the homepage widget after successfully processing a payment through PayPal webhooks. However, after the payment is successful, the app shows a blank space instead of navigating to the homepage. I've verified the payment success through the PayPal webhook, and I'm trying to handle the redirection in my Flutter app.

Code:

main.dart

 @override
  void initState() {
    super.initState();
    getUserData();
    
    _socketService = SocketService(onSubscriptionSuccess: (isPremium) {
      final currentUser = ref.read(userProvider.notifier).state;
      if (currentUser != null) {
        final updatedUser = currentUser.copyWith(
          isPremium: isPremium,
      
        );
        ref.read(userProvider.notifier).state = updatedUser;
        Routemaster.of(context).replace(HOME_ROUTE);
      }
    });
    _socketService.createSocketConnection();
  }

socket_service.dart

import 'package:socket_io_client/socket_io_client.dart' as IO;

void createSocketConnection() {
  socket = IO.io('http://localhost:3001', <String, dynamic>{
    // Connection setup
  });

  socket.onConnect((_) => {
    // Connection established
  });
  socket.on('subscription_success', (data) => onSubscriptionSuccessHandler(data));
}

void onSubscriptionSuccessHandler(data) {
  if (data != null && data['isPremium'] != null) {
    bool isPremium = data['isPremium'];
    onSubscriptionSuccess(isPremium);
  }
}

router.dart

routes: {
    HOME_ROUTE: (route) => const MaterialPage<void>(child: HomePage()),

Server-side Node.js

index.js


const { Server } = require("socket.io");


const server = http.createServer(app);
const io = new Server(server);

app.use((req, res, next) => {
  req.io = io;
  next();
});

redirectedToPremiunFeatures = true;

io.on("connection", (socket) => {
  socket.emit("user", redirectedToPremiunFeatures);
 
  socket.on("redirected", (reason) => {
    redirectedToPremiunFeatures = true;
    socket.emit("user", redirectedToPremiunFeatures);
    socket.broadcast.emit("user", redirectedToPremiunFeatures);
    
  });
  socket.on("reconnect_attempt", () => {
    
  });
});

server.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

paypal.js


paypalRouter.post("/subscriptions/webhook", webhookRateLimiter, async (req, res) => {
...
   if (updatedUser) {
              console.log("Subscription confirmed for user:", userId);
              req.io.emit("subscription_success", {
                userId: userId,
                isPremium: true,
              });

socket_service.dart and Server-side logic (Node.js with socket.io) handle the subscription success event and are supposed to trigger the onSubscriptionSuccess callback in main.dart.

Despite the callback being triggered (confirmed via debug logs), the app doesn't navigate to the HomePage widget as expected. It's worth noting that the rest of my navigation setup works fine in other parts of the app.

How can I ensure the app navigates to the homepage after receiving a successful payment notification from the PayPal webhook?


Solution

  • Without diagnosing the specific problem here, as a design matter webhooks shouldn't be used to trigger client-side events. Their purpose is to update your backend with state changes, i.e. mark the subscription as paid after initial approval and after every cycle (PAYMENT.SALE.COMPLETED event). Use webhooks for that purpose.

    On the client side, have it call the server to check if the subscription is currently active. If it is not (i.e. no webhook has yet been received and processed to mark it as yes paid through a certain date), have the server do a GET call to retrieve the subscription's status, and update the record accordingly independent of the webhook (which may occasionally be delayed). Return the result to the client immediately, allowing it to proceed (or not) to whatever features the subscription enables.