Пример #1
0
 /**
  * Cancel any payments that have not completed.
  */
 public function tidyPayments()
 {
     foreach ($this->Payments() as $payment) {
         if (!$payment->isComplete()) {
             $response = PurchaseService::create($payment)->cancelPurchase();
         }
     }
 }
 /**
  * Create a payment model, and provide link to redirect to external gateway,
  * or redirect to order link.
  * @return string - url for redirection after payment has been made
  */
 public function makePayment($gateway, $gatewaydata = array())
 {
     //create payment
     $payment = $this->createPayment($gateway);
     if (!$payment) {
         //errors have been stored.
         return false;
     }
     // Create a purchase service, and set the user-facing success URL for redirects
     $service = PurchaseService::create($payment)->setReturnUrl($this->getReturnUrl());
     // Process payment, get the result back
     $response = $service->purchase($this->getGatewayData($gatewaydata));
     if (GatewayInfo::is_manual($gateway)) {
         //don't complete the payment at this stage, if payment is manual
         $this->placeOrder();
     } elseif ($response->isSuccessful()) {
         $this->completePayment();
     }
     return $response;
 }
 /**
  * The main action for handling all requests.
  * It will redirect back to the application in all cases,
  * but will not update the Payment/Transaction models if they are not found,
  * or allowed to be updated.
  */
 public function index()
 {
     $payment = $this->getPayment();
     if (!$payment) {
         return $this->httpError(404, _t("Payment.NOTFOUND", "Payment could not be found."));
     }
     //isolate the gateway request message containing success / failure urls
     $message = $payment->Messages()->filter("ClassName", array("PurchaseRequest", "AuthorizeRequest"))->first();
     $service = PurchaseService::create($payment);
     //redirect if payment is already a success
     if ($payment->isComplete()) {
         return $this->redirect($this->getSuccessUrl($message));
     }
     //do the payment update
     $response = null;
     switch ($this->request->param('Status')) {
         case "complete":
             $serviceResponse = $service->completePurchase();
             if ($serviceResponse->isSuccessful()) {
                 $response = $this->redirect($this->getSuccessUrl($message));
             } else {
                 $response = $this->redirect($this->getFailureUrl($message));
             }
             break;
         case "notify":
             $serviceResponse = $service->completePurchase();
             // Allow implementations where no redirect happens,
             // since gateway failsafe callbacks might expect a 2xx HTTP response
             $response = new SS_HTTPResponse('', 200);
             break;
         case "cancel":
             //TODO: store cancellation message / void payment
             $response = $this->redirect($this->getFailureUrl($message));
             break;
         default:
             $response = $this->httpError(404, _t("Payment.INVALIDURL", "Invalid payment url."));
     }
     return $response;
 }
 public function testNonExistantGateway()
 {
     //exception when trying to run functions that require a gateway
     $payment = $this->payment;
     $service = PurchaseService::create($payment->init("PxPayGateway", 100, "NZD"))->setReturnUrl("complete");
     $this->setExpectedException("RuntimeException");
     try {
         $result = $service->purchase();
     } catch (RuntimeException $e) {
         $this->markTestIncomplete();
         $totalNZD = Payment::get()->filter('MoneyCurrency', "NZD")->sum();
         $this->assertEquals(27.23, $totalNZD);
         $service->purchase();
         $service->completePurchase();
         //just to assert that exception is thrown
         throw $e;
     }
 }
 /**
  * Process the form that is submitted through the site. Note that omnipay fields are NOT saved to the database.
  * This is intentional (so we don't save credit card details) but should be fixed in future, so we save all fields,
  * but only save the last 3 digits of the credit card (and not the CVV/exp date)
  *
  * @todo: save all fields to database except credit card fields
  *
  * @param array $data
  * @param Form  $form
  *
  * @return Redirection
  */
 public function process($data, $form)
 {
     Session::set("FormInfo.{$form->FormName()}.data", $data);
     Session::clear("FormInfo.{$form->FormName()}.errors");
     foreach ($this->Fields() as $field) {
         $messages[$field->Name] = $field->getErrorMessage()->HTML();
         $formField = $field->getFormField();
         if ($field->Required && $field->CustomRules()->Count() == 0) {
             if (isset($data[$field->Name])) {
                 $formField->setValue($data[$field->Name]);
             }
             if (!isset($data[$field->Name]) || !$data[$field->Name] || !$formField->validate($form->getValidator())) {
                 $form->addErrorMessage($field->Name, $field->getErrorMessage(), 'bad');
             }
         }
     }
     if (Session::get("FormInfo.{$form->FormName()}.errors")) {
         Controller::curr()->redirectBack();
         return;
     }
     // if there are no errors, create the payment
     $submittedForm = Object::create('SubmittedPaymentForm');
     $submittedForm->SubmittedByID = ($id = Member::currentUserID()) ? $id : 0;
     $submittedForm->ParentID = $this->ID;
     // if saving is not disabled save now to generate the ID
     if (!$this->DisableSaveSubmissions) {
         $submittedForm->write();
     }
     $attachments = array();
     $submittedFields = new ArrayList();
     foreach ($this->Fields() as $field) {
         if (!$field->showInReports()) {
             continue;
         }
         $submittedField = $field->getSubmittedFormField();
         $submittedField->ParentID = $submittedForm->ID;
         $submittedField->Name = $field->Name;
         $submittedField->Title = $field->getField('Title');
         // save the value from the data
         if ($field->hasMethod('getValueFromData')) {
             $submittedField->Value = $field->getValueFromData($data);
         } else {
             if (isset($data[$field->Name])) {
                 $submittedField->Value = $data[$field->Name];
             }
         }
         if (!empty($data[$field->Name])) {
             if (in_array("EditableFileField", $field->getClassAncestry())) {
                 if (isset($_FILES[$field->Name])) {
                     $foldername = $field->getFormField()->getFolderName();
                     // create the file from post data
                     $upload = new Upload();
                     $file = new File();
                     $file->ShowInSearch = 0;
                     try {
                         $upload->loadIntoFile($_FILES[$field->Name], $file, $foldername);
                     } catch (ValidationException $e) {
                         $validationResult = $e->getResult();
                         $form->addErrorMessage($field->Name, $validationResult->message(), 'bad');
                         Controller::curr()->redirectBack();
                         return;
                     }
                     // write file to form field
                     $submittedField->UploadedFileID = $file->ID;
                     // attach a file only if lower than 1MB
                     if ($file->getAbsoluteSize() < 1024 * 1024 * 1) {
                         $attachments[] = $file;
                     }
                 }
             }
         }
         $submittedField->extend('onPopulationFromField', $field);
         if (!$this->DisableSaveSubmissions) {
             $submittedField->write();
         }
         $submittedFields->push($submittedField);
     }
     /** Do the payment **/
     // move this up here for our redirect link
     $referrer = isset($data['Referrer']) ? '?referrer=' . urlencode($data['Referrer']) : "";
     // set amount
     $currency = $this->data()->PaymentCurrency;
     $paymentfieldname = $this->PaymentAmountField()->Name;
     $amount = $data[$paymentfieldname];
     $postdata = $data;
     // request payment
     $payment = Payment::create()->init($this->data()->PaymentGateway, $amount, $currency);
     $payment->write();
     $response = PurchaseService::create($payment)->setReturnUrl($this->Link('finished') . $referrer)->setCancelUrl($this->Link('finished') . $referrer)->purchase($postdata);
     // save payment to order
     $submittedForm->PaymentID = $payment->ID;
     $submittedForm->write();
     $emailData = array("Sender" => Member::currentUser(), "Fields" => $submittedFields);
     $this->extend('updateEmailData', $emailData, $attachments);
     $submittedForm->extend('updateAfterProcess');
     Session::clear("FormInfo.{$form->FormName()}.errors");
     Session::clear("FormInfo.{$form->FormName()}.data");
     // set a session variable from the security ID to stop people accessing the finished method directly
     if (isset($data['SecurityID'])) {
         Session::set('FormProcessed', $data['SecurityID']);
     } else {
         // if the form has had tokens disabled we still need to set FormProcessed
         // to allow us to get through the finshed method
         if (!$this->Form()->getSecurityToken()->isEnabled()) {
             $randNum = rand(1, 1000);
             $randHash = md5($randNum);
             Session::set('FormProcessed', $randHash);
             Session::set('FormProcessedNum', $randNum);
         }
     }
     if (!$this->DisableSaveSubmissions) {
         Session::set('userformssubmission' . $this->ID, $submittedForm->ID);
     }
     return $response->redirect();
 }
 public function testRedirectUrl()
 {
     $service = PurchaseService::create(new Payment())->setReturnUrl("abc/123")->setCancelUrl("xyz/blah/2345235?andstuff=124124#hash");
     $this->assertEquals("abc/123", $service->getReturnUrl());
     $this->assertEquals("xyz/blah/2345235?andstuff=124124#hash", $service->getCancelUrl());
 }
Пример #7
0
 /**
  * Initiate the actual purchase, and do redirect to
  * gateway site, success url or cancel url.
  * @param  Payment $payment
  * @param  array $data
  */
 protected function processPayment(Payment $payment, $data)
 {
     $response = PurchaseService::create($payment)->setReturnUrl($this->successurl)->setCancelUrl($this->cancelurl)->setManualPurchaseStatus("Captured")->purchase($data);
     return $response->redirect();
 }