/**
  * Process the Express Checkout RETURNURL
  */
 public function paypalResponseSuccess()
 {
     $form_id = $_GET['ab_fid'];
     $paypal = new AB_PayPal();
     if (isset($_GET["token"]) && isset($_GET["PayerID"])) {
         $token = $_GET["token"];
         $payer_id = $_GET["PayerID"];
         // send the request to PayPal
         $response = $paypal->sendNvpRequest('GetExpressCheckoutDetails', sprintf('&TOKEN=%s', $token));
         if (strtoupper($response["ACK"]) == "SUCCESS") {
             $data = sprintf('&TOKEN=%s&PAYERID=%s&PAYMENTREQUEST_0_PAYMENTACTION=Sale', $token, $payer_id);
             // response keys containing useful data to send via DoExpressCheckoutPayment operation
             $response_data_keys_pattern = sprintf('/^(%s)/', implode('|', array('PAYMENTREQUEST_0_AMT', 'PAYMENTREQUEST_0_ITEMAMT', 'PAYMENTREQUEST_0_CURRENCYCODE', 'L_PAYMENTREQUEST_0')));
             foreach ($response as $key => $value) {
                 // collect product data from response using defined response keys
                 if (preg_match($response_data_keys_pattern, $key)) {
                     $data .= sprintf('&%s=%s', $key, $value);
                 }
             }
             //We need to execute the "DoExpressCheckoutPayment" at this point to Receive payment from user.
             $response = $paypal->sendNvpRequest('DoExpressCheckoutPayment', $data);
             if ("SUCCESS" == strtoupper($response["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($response["ACK"])) {
                 // get transaction info
                 $response = $paypal->sendNvpRequest('GetTransactionDetails', "&TRANSACTIONID=" . urlencode($response["PAYMENTINFO_0_TRANSACTIONID"]));
                 if ("SUCCESS" == strtoupper($response["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($response["ACK"])) {
                     // need session to get Total and Token
                     $token = $_SESSION['bookly'][$form_id]['paypal_response'][0]['TOKEN'];
                     $userData = new AB_UserBookingData($form_id);
                     $userData->load();
                     if ($userData->get('service_id')) {
                         $appointment = $userData->save();
                         $customer_appointment = new AB_CustomerAppointment();
                         $customer_appointment->loadBy(array('appointment_id' => $appointment->get('id'), 'customer_id' => $userData->getCustomerId()));
                         $payment = new AB_Payment();
                         $payment->set('token', urldecode($token));
                         $payment->set('total', $userData->getFinalServicePrice() * $userData->get('number_of_persons'));
                         $payment->set('customer_appointment_id', $customer_appointment->get('id'));
                         $payment->set('transaction', urlencode($response["TRANSACTIONID"]));
                         $payment->set('created', current_time('mysql'));
                         $payment->save();
                         $userData->setPayPalStatus('success');
                     }
                     @wp_redirect(remove_query_arg(array('action', 'token', 'PayerID', 'ab_fid'), AB_Utils::getCurrentPageURL()));
                     exit(0);
                 } else {
                     header('Location: ' . wp_sanitize_redirect(add_query_arg(array('action' => 'ab-paypal-errorurl', 'ab_fid' => $form_id, 'error_msg' => $response["L_LONGMESSAGE0"]), AB_Utils::getCurrentPageURL())));
                     exit;
                 }
             } else {
                 header('Location: ' . wp_sanitize_redirect(add_query_arg(array('action' => 'ab-paypal-errorurl', 'ab_fid' => $form_id, 'error_msg' => $response["L_LONGMESSAGE0"]), AB_Utils::getCurrentPageURL())));
                 exit;
             }
         } else {
             header('Location: ' . wp_sanitize_redirect(add_query_arg(array('action' => 'ab-paypal-errorurl', 'ab_fid' => $form_id, 'error_msg' => 'Invalid token provided'), AB_Utils::getCurrentPageURL())));
             exit;
         }
     } else {
         throw new Exception('Token parameter not found!');
     }
 }