1 <?php
2
3
4 class UnitellerPayment extends PaymentMethod {
5 static $db = array(
6 'TestMode' => 'Boolean',
7
8 'Login' => 'Varchar',
9 'Password' => 'Varchar(150)',
10 'ShopID' => 'Varchar',
11 'BaseURL' => 'Varchar(100)',
12
13 'TestLogin' => 'Varchar',
14 'TestPassword' => 'Varchar(150)',
15 'TestShopID' => 'Varchar',
16 'TestBaseURL' => 'Varchar(100)',
17
18 'MeanType' => 'Varchar',
19 'EMoneyType' => 'Varchar',
20 'LifeTime' => 'Varchar',
21
22 );
23
24 static $defaults = array(
25 'BaseURL' => 'https://wpay.uniteller.ru/',
26 'TestBaseURL' => 'https://test.wpay.uniteller.ru/',
27 'MeanType' => '',
28 'EMoneyType' => '',
29 'LifeTime' => ''
30 );
31
32 static $paymentMethodIcons = array(
33 'cart_payment/img/Visa.png',
34 );
35
36 static $meanTypes = array(
37 '1' => 'VISA',
38 '2' => 'MasterCard',
39 '3' => 'DinersClub',
40 '4' => 'JCB',
41
42 );
43
44 static function getMeanTypes() {
45 $rs = array();
46 $rs[''] = _t('Payment.Any','Any');
47 foreach(self::$meanTypes as $key=>$type)
48 $rs[$key] = $type;
49
50 return $rs;
51
52 }
53
54 static $eMoneyTypes = array(
55 '1' => 'YandexMoney',
56 '2' => 'RBKMoney',
57 '3' => 'MoneyMail',
58 '4' => 'WebCreds',
59 '5' => 'EasyPay',
60 '6' => 'PlatezhRu',
61 '7' => 'DengiMail',
62 '8' => 'Megafon',
63 '9' => 'MTS',
64 '10' => 'Beeline',
65 '11' => 'PayPal',
66 '12' => 'VK',
67 '13' => 'Euroset',
68 '14' => 'YotaMoney',
69 '15' => 'QIWI',
70 '16' => 'PlatPhone',
71 '17' => 'MoneyBookers',
72 '29' => 'WebmoneyWMR'
73 );
74
75 static function getEMoneyTypes() {
76 $rs = array();
77 $rs[''] = _t('Payment.Any','Any');
78 foreach(self::$eMoneyTypes as $key=>$type)
79 $rs[$key] = _t('UnitellerPayment.EMoneyType_' . $type, $type);
80 return $rs;
81
82 }
83
84 function getPaymentHandler() {
85 return 'UnitellerPayment_Handler';
86 }
87
88 function getCMSFields() {
89 $fields = parent::getCMSFields();
90 $fields->findOrMakeTab('Root.Settings', _t('PaymentMethod.tab_Settings','Settings'));
91
92 $fields->addFieldToTab('Root.Settings', new DropdownField('MeanType', $this->fieldLabel('MeanType'), self::getMeanTypes(), $this->MeanType));
93 $fields->addFieldToTab('Root.Settings', new DropdownField('EMoneyType', $this->fieldLabel('EMoneyType'), self::getEMoneyTypes(), $this->EMoneyType));
94 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('LifeTime'));
95
96 $fields->addFieldToTab('Root.Settings', new HeaderField('TestSettings', _t('PaymentMethod.WorkSettings', 'Work Settings')));
97 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('Login'));
98 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('Password'));
99 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('ShopID'));
100 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('BaseURL'));
101
102 $fields->addFieldToTab('Root.Settings', new HeaderField('TestSettings', _t('PaymentMethod.TestSettings', 'Test Settings')));
103 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('TestLogin'));
104 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('TestPassword'));
105 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('TestShopID'));
106 $fields->addFieldToTab('Root.Settings', $fields->dataFieldByName('TestBaseURL'));
107
108 return $fields;
109 }
110
111 public function validate() {
112 if ($this->Active) {
113 if (!$this->Login)
114 return new ValidationResult(false, _t('UnitellerPayment.WrongLogin', 'Wrong Login'));
115 if (!$this->Password)
116 return new ValidationResult(false, _t('UnitellerPayment.WrongPassword', 'Wrong Password'));
117 if (!$this->ShopID)
118 return new ValidationResult(false, _t('UnitellerPayment.WrongShopID', 'Wrong ShopID'));
119 if (!$this->BaseURL)
120 return new ValidationResult(false, _t('UnitellerPayment.WrongBaseURL', 'Wrong BaseURL'));
121 }
122 if ($this->TestMode) {
123 if (!$this->TestLogin)
124 return new ValidationResult(false, _t('UnitellerPayment.WrongTestLogin', 'Wrong Test Login'));
125 if (!$this->TestPassword)
126 return new ValidationResult(false, _t('UnitellerPayment.WrongTestPassword', 'Wrong Test Password'));
127 if (!$this->TestShopID)
128 return new ValidationResult(false, _t('UnitellerPayment.WrongTestShopID', 'Wrong Test ShopID'));
129 if (!$this->TestBaseURL)
130 return new ValidationResult(false, _t('UnitellerPayment.WrongTestBaseURL', 'Wrong Test BaseURL'));
131 }
132 return new ValidationResult();
133 }
134
135
136 function Password() {
137 return ($this->TestMode) ? $this->TestPassword : $this->Password;
138 }
139
140 function Login() {
141 return ($this->TestMode) ? $this->TestLogin : $this->Login;
142 }
143
144 function ShopID() {
145 return ($this->TestMode) ? $this->TestShopID : $this->ShopID;
146 }
147
148 function BaseURL() {
149 return ($this->TestMode) ? $this->TestBaseURL : $this->BaseURL;
150 }
151
152 function MeanType() {
153 return ($this->MeanType) ? $this->MeanType : '';
154 }
155
156 function EMoneyType() {
157 return ($this->EMoneyType) ? $this->EMoneyType : '';
158 }
159
160 function LifeTime() {
161 return ($this->LifeTime) ? $this->LifeTime : '';
162 }
163
164
165 function processPayment($payment) {
166 if ($payment->Status != 'Failure' && $payment->Status != 'Success') {
167 $payment->Status = 'Pending';
168 $payment->write();
169 $link = $this->paymentLink($payment->ID);
170 return new Payment_Processing($link);
171 } else {
172
173 }
174 }
175
176
177 function getClearPaymentLink($payment) {
178 return Director::absoluteURL(UnitellerPayment_Handler::form_link($payment->ID));
179 }
180
181 182 183 184 185
186 function getForm($payment) {
187 $orderCost = $payment->PaidObject()->getTotalPrice();
188 $responseURL = Director::absoluteURL(UnitellerPayment_Handler::return_link());
189 $url = $this->BaseURL() . 'pay/';
190 $shopID = $this->ShopID();
191 $signature = $this->getSignature($payment->ID, $orderCost);
192 $html = '<form id="PaymentForm" action="'.$url.'" method="post" enctype="application/x-www-form-urlencoded">';
193 $html .= '<input type="hidden" name="Shop_IDP" value="'.$shopID.'" />';
194 $html .= '<input type="hidden" name="Order_IDP" value="'.$payment->ID.'" />';
195 $html .= '<input type="hidden" name="Subtotal_P" value="'.$orderCost.'" />';
196 $html .= '<input type="hidden" name="Signature" value="'.$signature.'" />';
197 $html .= '<input type="hidden" name="URL_RETURN" value="'.$responseURL.'" />';
198 $html .= '<input type="submit" value="Оплатить" />';
199 $html .= '</form>';
200 return $html;
201 }
202
203
204 function getRequestSignature($orderID, $status) {
205 $realSignature = strtoupper(md5($orderID . $status . $this->Password()));
206 return $realSignature;
207 }
208
209
210 function getSignature($orderID, $orderSum) {
211 return strtoupper(md5(
212 md5($this->ShopID()) .
213 '&' . md5($orderID) .
214 '&' . md5($orderSum) .
215 '&' . md5($this->MeanType()) .
216 '&' . md5($this->EMoneyType()) .
217 '&' . md5($this->LifeTime()) .
218 '&' . md5('') .
219 '&' . md5('') .
220 '&' . md5('') .
221 '&' . md5('') .
222 '&' . md5($this->Password())
223 ));
224 }
225
226 227 228 229
230 function checkPaymentResult($payment) {
231 if ($payment->Status != 'Success') {
232 $data = $this->getAuthResult($payment->ID);
233 $payment->PaymentResponse = serialize($data);
234 if (isset($data['error'])) {
235 $payment->Status = 'Failure';
236 $payment->Message = _t('UnitellerPayment.FAILURE', 'Заказ не оплачен');
237 }
238 else {
239 if ($data['Status'] == 'Authorized' || $data['Status'] == 'Paid') {
240 $payment->Status = 'Success';
241 $payment->Message = _t('UnitellerPayment.DONE', 'Заказ оплачен');
242 $payment->TransactionID = $data['BillNumber'];
243 }
244 else {
245 $payment->Status = 'Failure';
246 $payment->Message = _t('UnitellerPayment.FAILURE', 'Заказ не оплачен');
247 }
248 }
249 $payment->write();
250 }
251 }
252
253
254
255 function getAuthResult($orderID) {
256 $sPostFields = array(
257 'Shop_ID' => $this->ShopID(),
258 'Login' => $this->Login(),
259 'Password' => $this->Password(),
260 'Format' => 1,
261 'ShopOrderNumber' => $orderID,
262 'S_FIELDS' => 'Status;Error_Code;Error_Comment;ApprovalCode;BillNumber;Total;Response_Code;Recommendation;CardNumber;Date;CardHolder'
263 );
264 $ch = curl_init();
265 curl_setopt($ch, CURLOPT_URL, $this->BaseURL() . "results/");
266 curl_setopt($ch, CURLOPT_HEADER, 0);
267 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
268 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
269 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
270 curl_setopt($ch, CURLOPT_VERBOSE, 0);
271 curl_setopt($ch, CURLOPT_TIMEOUT, 60);
272 curl_setopt($ch, CURLOPT_POST, 1);
273 curl_setopt($ch, CURLOPT_POSTFIELDS, $sPostFields);
274 curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
275 curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
276 $curl_response = curl_exec($ch);
277 $curl_error = curl_error($ch);
278
279 $data = array();
280 if ($curl_error) {
281
282 $data['error'] = $curl_error;
283 } else {
284
285 $arr = explode( ";", $curl_response );
286 if ( count($arr) >= 11 ) {
287 $data = array(
288 "Status" => $arr[0] ,
289 "Error_Code" => $arr[1] ,
290 "Error_Comment" => $arr[2],
291 "ApprovalCode" => $arr[3],
292 "BillNumber" => $arr[4],
293 "Total" => $arr[5],
294 "ResponseCode" => $arr[6],
295 "Recommendation" => $arr[7],
296 "CardNumber" => $arr[8],
297 "Date" => $arr[9],
298 "CardHolder" => $arr[10]
299 );
300 } else {
301
302 if ($curl_response) {
303 $data['error'] = $curl_response;
304 } else {
305 $data['error'] = 'Платеж не совершен!';
306 }
307
308 }
309 }
310 return $data;
311 }
312 }
313
314
315 316 317
318 class UnitellerPayment_Handler extends Payment_Handler {
319
320 static $URLSegment = 'uniteller';
321
322 static function form_link($paymentID) {
323 return self::$URLSegment . '/show_form?paym_id=' . $paymentID;
324 }
325
326 static function return_link() {
327 return self::$URLSegment . '/process';
328 }
329
330 function show_form() {
331 if (isset($_GET['paym_id'])) {
332 $paymentID = (int)$_GET['paym_id'];
333 if ($payment = DataObject::get_by_id('Payment', $paymentID)) {
334 return $this->customise(array(
335 'Form' => $payment->PaymentType()->getForm($payment)
336 ))->renderWith(array('UnitellerPayment_form'));
337 }
338 }
339 return false;
340 }
341
342 343 344
345 function process() {
346 if (isset($_GET['Order_ID'])) {
347 $orderID = (int)$_GET['Order_ID'];
348 if ($payment = DataObject::get_by_id('Payment', $orderID)) {
349 $payment->PaymentType()->checkPaymentResult($payment);
350 Director::redirect(CheckoutPage::find_link('order/' . $payment->PaidObject()->HashLink));
351 }
352 }
353 }
354
355
356 function changeOrderStatus() {
357 if ( count($_POST) && isset($_POST["Order_ID"]) && isset($_POST["Status"]) && isset($_POST["Signature"]) ) {
358 $orderID = (int)$_POST["Order_ID"];
359 if ($payment = DataObject::get_by_id('Payment', $orderID)) {
360 $realSignature = $payment->PaymentType()->getRequestSignature($_POST["Order_ID"], $_POST["Status"]);
361 if (trim((string)$_POST["Signature"]) == $realSignature) {
362 $payment->PaymentType()->checkPaymentResult($payment);
363 }
364 }
365 }
366 }
367 }
368
[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.
-