public function callback($request)
    {
        $this->extend('onBeforeCallback');
        
        $data = $this->request->postVars();
        $status = "error";
        $order_id = 0;
        $payment_id = 0;

        $error_url = Controller::join_links(
            Director::absoluteBaseURL(),
            Payment_Controller::config()->url_segment,
            'complete',
            'error'
        );

        // Check if CallBack data exists and install id matches the saved ID
        if (isset($data) && isset($data['custom']) && isset($data['payment_status'])) {
            $order_id = $data['custom'];
            $paypal_request = 'cmd=_notify-validate';
            $final_response = "";
            
            // If the transaction ID is set, keep it
            if (array_key_exists("txn_id", $data)) {
                $payment_id = $data["txn_id"];
            }
            
            $listener = new PaypalIPN();
            
            if (Director::isDev()) {
                $listener->useSandbox();
            }

            try {
                $verified = $listener->verifyIPN();
            } catch (Exception $e) {
                error_log("Unable to verify IPN: " . $e->getMessage());
                return $this->httpError(500);
            }

            if ($verified) {
                // IPN response was "VERIFIED"
                switch ($data['payment_status']) {
                    case 'Canceled_Reversal':
                        $status = "canceled";
                        break;
                    case 'Completed':
                        $status = "paid";
                        break;
                    case 'Denied':
                        $status = "failed";
                        break;
                    case 'Expired':
                        $status = "failed";
                        break;
                    case 'Failed':
                        $status = "failed";
                        break;
                    case 'Pending':
                        $status = "pending";
                        break;
                    case 'Processed':
                        $status = "pending";
                        break;
                    case 'Refunded':
                        $status = "refunded";
                        break;
                    case 'Reversed':
                        $status = "canceled";
                        break;
                    case 'Voided':
                        $status = "canceled";
                        break;
                }
            } else {
                error_log("Invalid payment status");
                return $this->httpError(500);
            }
        } else {
            error_log("No payment details set");
            return $this->httpError(500);
        }
        
        $payment_data = ArrayData::array_to_object(array(
            "OrderID" => $order_id,
            "PaymentProvider" => "PayPal",
            "PaymentID" => $payment_id,
            "Status" => $status,
            "GatewayData" => $data
        ));
        
        $this->setPaymentData($payment_data);
        
        $this->extend('onAfterCallback');
        
        return $this->httpError(200);
    }