Version: current

      1 <?php
      2 // Способ оплаты через PayPal
      3 class PayPalPayment extends PaymentMethod {
      4     static $db = array(
      5         'RecieverEmail' => 'Varchar(200)',
      6         'AuthorisationCode' => 'Text',
      7
      8         'TestMode' => 'Boolean',
      9         'BaseURL' => 'Varchar(150)',
     10         'TestBaseURL' => 'Varchar(150)',
     11     );
     12
     13     static $defaults = array(
     14         'BaseURL' => 'https://www.paypal.com/cgi-bin/webscr',
     15         'TestBaseURL' => 'https://www.sandbox.paypal.com/cgi-bin/webscr',
     16     );
     17
     18     static $paymentMethodIcons = array(
     19         'cart_payment/img/PayPalPayment.png',
     20     );
     21
     22     /*
     23      * Возвращаем созданный способ оплаты через PayPal
     24      *
     25      * @return DataObject
     26      */
     27     static function getPaymentMethod() {
     28         return DataObject::get_one('PayPalPayment', 'Active = 1');
     29     }
     30
     31     function onBeforeWrite() {
     32         parent::onBeforeWrite();
     33
     34         if (!$this->AuthorisationCode) {
     35             $this->AuthorisationCode = md5(uniqid(rand(), true));
     36         }
     37     }
     38
     39     function getCMSFields() {
     40         $fields = parent::getCMSFields();
     41         $fields->findOrMakeTab('Root.Settings', _t('PaymentMethod.tab_Settings','Settings'));
     42
     43         $fields->addFieldToTab('Root.Settings', new HeaderField('WorkSettings', _t('PaymentMethod.WorkSettings', 'Work Settings')));
     44         $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('BaseURL'));
     45
     46         $fields->addFieldToTab('Root.Settings', new HeaderField('TestSettings', _t('PaymentMethod.TestSettings', 'Test Settings')));
     47         $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('TestBaseURL'));
     48
     49         $fields->removeByName('AuthorisationCode');
     50         return $fields;
     51     }
     52
     53     function BaseURL() {
     54         return ($this->TestMode) ? $this->TestBaseURL : $this->BaseURL;
     55     }
     56
     57     /*
     58      * Форма оплаты PayPal
     59      *
     60      * @return Form
     61      */
     62     function getForm($payment) {
     63         $orderCost = $payment->PaidObject()->getTotalPrice();
     64         $responseURL = Director::absoluteURL(PayPalPayment_Handler::return_link());
     65         $url = $this->BaseURL() . 'pay/';
     66
     67         $html = '<form id="PaymentForm" action="'.$url.'" method="post" enctype="application/x-www-form-urlencoded">';
     68
     69         $html .= '<input type="hidden" name="cmd" value="_cart">'; // загрузка корзины в PayPal
     70         $html .= '<input type="hidden" name="upload" value="1">';
     71
     72         $html .= '<input type="hidden" name="business" value="'.($this->RecieverEmail ? $this->RecieverEmail : SiteConfig::current_site_config()->CartAdminEmail()).'">';
     73
     74         $html .= '<input type="hidden" name="custom" value="'.$payment->HashLink . '-' . $this->AuthorisationCode.'">';
     75         $html .= '<input type="hidden" name="return" value="'.$responseURL.'">';
     76         $html .= '<input type="hidden" name="rm" value="2">';
     77
     78         $cpt = 0;
     79         $items = $payment->PaidObject()->Items();
     80         foreach($items as $item) {
     81             $html .= '<input type="hidden" name="item_name_' . ++$cpt.'" value="'.$item->Title.'">';
     82             $html .= '<input type="hidden" name="amount_' . $cpt.'" value="'.$item->ItemPrice.'">';
     83             $html .= '<input type="hidden" name="quantity_' . $cpt.'" value="'.$item->Quantity.'">';
     84         }
     85
     86         $html .= '<input type="hidden" name="currency_code" value="RUB">';  //USD
     87         $html .= '<input type="hidden" name="lc" value="RU">'; //US
     88         //$html .= '<input type="hidden" name="bn" value="PP-BuyNowBF">';
     89
     90         $html .= '<input type="submit" value="Оплатить" />';
     91         $html .= '</form>';
     92         return $html;
     93     }
     94
     95     // можно вызвать повторно, у уже сформированного платежа (отправть пользователю на почту)
     96     function processPayment($payment) {
     97         if ($payment->Status != 'Failure' && $payment->Status != 'Success') {
     98             $payment->Status = 'Pending';
     99             $payment->write();
    100             $link = $this->paymentLink($payment->ID);
    101             return new Payment_Processing($link);
    102         } else {
    103             return new Payment_Failure($payment->ExceptionError);
    104         }
    105     }
    106
    107     // "чистая" ссылка (URL) на оплату
    108     function getClearPaymentLink($payment) {
    109         return Director::absoluteURL(PayPalPayment_Handler::form_link($payment->HashLink));
    110     }
    111
    112     /*
    113      * Проверка результатов совершения платежа
    114      *
    115      */
    116     function completePayment($payment) {
    117         if ($payment->Status != 'Success') {
    118             $payment->Status = 'Success';
    119             $payment->Message = _t('PayPalPayment.DONE', 'Заказ оплачен');
    120             $payment->write();
    121         }
    122     }
    123 }
    124
    125 /**
    126  * Handler for responses from the YaMoney
    127  */
    128 class PayPalPayment_Handler extends Payment_Handler {
    129
    130     static $URLSegment = 'paypal';
    131
    132     static function form_link($hash) {
    133         return self::$URLSegment . '/show_form?hash=' . $hash;
    134     }
    135
    136     function show_form() {
    137         if (isset($_GET['hash'])) {
    138             $hash = Convert::raw2sql($_GET['hash']);
    139             if ($payment = DataObject::get_one('Payment', "HashLink = '{$hash}'")) {
    140                 return $this->customise(array(
    141                     'Form' => $payment->PaymentType()->getForm($payment)
    142                 ))->renderWith(array('PayPalPayment_form'));
    143             }
    144         }
    145         return false;
    146     }
    147
    148     static function return_link() {
    149         return self::$URLSegment . '/complete';
    150     }
    151
    152     function complete() {
    153         if(isset($_REQUEST['custom']) && $custom = $_REQUEST['custom']) {
    154             $params = explode('-', $custom);
    155             if(count($params) == 2) {
    156                 $hash = Convert::raw2sql($params[0]);
    157                 if($payment = DataObject::get_one('Payment', "HashLink = '{$hash}'")) {
    158                     $payment->PaymentResponse = serialize($_REQUEST);
    159                     $paymentType = $payment->PaymentType();
    160                     if($paymentType->AuthorisationCode == $params[1]) {
    161                         if(isset($_REQUEST['payment_status']) && $_REQUEST['payment_status'] == 'Completed') {
    162                             $paymentType->completePayment($payment);
    163                         } else {
    164                             $payment->Status = 'Failure';
    165                             $payment->write();
    166                         }
    167                         Director::redirect(CheckoutPage::find_link('order/' . $payment->PaidObject()->HashLink));
    168                     }
    169                 }
    170             }
    171         }
    172     }
    173 }
    174

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -