You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

283 lines
7.5 KiB

4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
2 months ago
4 years ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
2 months ago
4 years ago
  1. <?php namespace Wpstudio\Sber\Classes;
  2. use OFFLINE\Mall\Classes\Payments\PaymentProvider;
  3. use OFFLINE\Mall\Classes\Payments\PaymentResult;
  4. use OFFLINE\Mall\Models\OrderProduct;
  5. use OFFLINE\Mall\Models\PaymentGatewaySettings;
  6. use OFFLINE\Mall\Models\OrderState;
  7. use OFFLINE\Mall\Models\Order;
  8. use Omnipay\Omnipay;
  9. use Omnipay\Sberbank\Message\AbstractRequest;
  10. use Omnipay\Sberbank\Message\AbstractResponse;
  11. use Omnipay\Sberbank\Message\AuthorizeRequest;
  12. use Omnipay\Sberbank\Message\AuthorizeResponse;
  13. use Throwable;
  14. use Session;
  15. use Lang;
  16. class SberCheckout extends PaymentProvider
  17. {
  18. /**
  19. * The order that is being paid.
  20. *
  21. * @var Order
  22. */
  23. public $order;
  24. /**
  25. * Data that is needed for the payment.
  26. * Card numbers, tokens, etc.
  27. *
  28. * @var array
  29. */
  30. public $data;
  31. /**
  32. * Return the display name of your payment provider.
  33. *
  34. * @return string
  35. */
  36. public function name(): string
  37. {
  38. return Lang::get('wpstudio.sber::lang.settings.sber_checkout');
  39. }
  40. /**
  41. * Return a unique identifier for this payment provider.
  42. *
  43. * @return string
  44. */
  45. public function identifier(): string
  46. {
  47. return 'sber';
  48. }
  49. /**
  50. * Validate the given input data for this payment.
  51. *
  52. * @return bool
  53. * @throws \October\Rain\Exception\ValidationException
  54. */
  55. public function validate(): bool
  56. {
  57. return true;
  58. }
  59. /**
  60. * Process the payment.
  61. *
  62. * @param PaymentResult $result
  63. *
  64. * @return PaymentResult
  65. */
  66. public function process(PaymentResult $result): PaymentResult
  67. {
  68. $gateway = $this->getGateway();
  69. try {
  70. $request = $gateway->authorize([
  71. 'orderNumber' => $this->order->id,
  72. 'amount' => $this->order->total_in_currency,
  73. 'returnUrl' => $this->returnUrl(),
  74. 'failUrl' => $this->cancelUrl(),
  75. 'description' => Lang::get('wpstudio.sber::lang.messages.order_number').$this->order->order_number,
  76. ]);
  77. assert($request instanceof AuthorizeRequest);
  78. $request->setOrderBundle($this->getOrderBundle());
  79. $response = $request->send();
  80. } catch (Throwable $e) {
  81. return $result->fail([], $e);
  82. }
  83. assert($response instanceof AuthorizeResponse);
  84. Session::put('mall.payment.callback', self::class);
  85. $this->setOrder($result->order);
  86. $result->order->payment_transaction_id = $response->getOrderId();
  87. $result->order->save();
  88. return $result->redirect($response->getRedirectResponse()->getTargetUrl());
  89. }
  90. /**
  91. * Gerenate sberbank orderBundle
  92. * @see https://securepayments.sberbank.ru/wiki/doku.php/integration:api:rest:requests:registerpreauth_cart#orderbundle
  93. *
  94. * @return array
  95. *
  96. */
  97. public function getOrderBundle()
  98. {
  99. $orderCreationDateFormatted = $this->order->created_at->format('Y-m-dTH:m:s');
  100. $cartItems = $this->getOrderCartItems();
  101. if ($cartItems) {
  102. return [
  103. 'orderCreationDate' => $orderCreationDateFormatted ?? '',
  104. 'cartItems' => $cartItems
  105. ];
  106. }
  107. return [];
  108. }
  109. /**
  110. * Create order cartitems for order bundle
  111. *
  112. * @return array
  113. */
  114. public function getOrderCartItems()
  115. {
  116. $cartItems = [];
  117. $items = [];
  118. foreach ($this->order->products as $positionId => $product) {
  119. assert($product instanceof OrderProduct);
  120. $items[] = [
  121. 'positionId' => $positionId + 1,
  122. 'name' => $product->name,
  123. 'quantity' => [
  124. 'value' => $product->quantity,
  125. 'measure' => 'шт.'
  126. ],
  127. 'itemCode' => $product->variant_id ?? $product->product_id,
  128. 'itemPrice' => $product->pricePostTaxes()->integer,
  129. ];
  130. }
  131. $cartItems['items'] = $items;
  132. return $cartItems;
  133. }
  134. /**
  135. * Y.K. has processed the payment and redirected the user back.
  136. *
  137. * @param PaymentResult $result
  138. *
  139. * @return PaymentResult
  140. */
  141. public function complete(PaymentResult $result): PaymentResult
  142. {
  143. $this->setOrder($result->order);
  144. $gateway = $this->getGateway();
  145. try {
  146. /**
  147. * It will be similar to calling methods `completeAuthorize()` and `completePurchase()`
  148. */
  149. $response = $gateway->orderStatus(
  150. [
  151. 'orderId' => $result->order->payment_transaction_id, // gateway order number
  152. 'language' => 'ru'
  153. ]
  154. )->send();
  155. } catch (Throwable $e) {
  156. return $result->fail([], $e);
  157. }
  158. assert($response instanceof AbstractResponse);
  159. $data = (array)$response->getData();
  160. if ( ! $response->isSuccessful()) {
  161. return $result->fail($data, $response);
  162. }
  163. return $result->success($data, $response);
  164. }
  165. /**
  166. * Build the Omnipay Gateway for PayPal.
  167. *
  168. * @return \Omnipay\Common\GatewayInterface
  169. */
  170. protected function getGateway()
  171. {
  172. $gateway = Omnipay::create('Sberbank');
  173. $gateway->setUserName(PaymentGatewaySettings::get('username'));
  174. $gateway->setPassword(decrypt(PaymentGatewaySettings::get('password')));
  175. if (PaymentGatewaySettings::get('sber_test_mode')) {
  176. $gateway->setTestMode(true);
  177. }
  178. return $gateway;
  179. }
  180. /**
  181. * Return any custom backend settings fields.
  182. *
  183. * These fields will be rendered in the backend
  184. * settings page of your provider.
  185. *
  186. * @return array
  187. */
  188. public function settings(): array
  189. {
  190. return [
  191. 'sber_test_mode' => [
  192. 'label' => 'wpstudio.sber::lang.settings.sber_test_mode',
  193. 'comment' => 'wpstudio.sber::lang.settings.sber_test_mode_label',
  194. 'span' => 'left',
  195. 'type' => 'switch',
  196. ],
  197. 'username' => [
  198. 'label' => Lang::get('wpstudio.sber::lang.settings.username'),
  199. 'comment' => Lang::get('wpstudio.sber::lang.settings.username_label'),
  200. 'span' => 'left',
  201. 'type' => 'text',
  202. ],
  203. 'password' => [
  204. 'label' => Lang::get('wpstudio.sber::lang.settings.password'),
  205. 'comment' => Lang::get('wpstudio.sber::lang.settings.password_label'),
  206. 'span' => 'left',
  207. 'type' => 'text',
  208. ],
  209. 'setPayedVirtualOrderAsComplete' => [
  210. 'label' => Lang::get('wpstudio.sber::lang.settings.set_payed_virtual_order_as_complete'),
  211. 'span' => 'left',
  212. 'type' => 'checkbox',
  213. ],
  214. ];
  215. }
  216. /**
  217. * Setting keys returned from this method are stored encrypted.
  218. *
  219. * Use this to store API tokens and other secret data
  220. * that is needed for this PaymentProvider to work.
  221. *
  222. * @return array
  223. */
  224. public function encryptedSettings(): array
  225. {
  226. return ['password'];
  227. }
  228. /**
  229. * Getting order state id by flag
  230. *
  231. * @param $orderStateFlag
  232. * @return int
  233. */
  234. protected function getOrderStateId($orderStateFlag): int
  235. {
  236. $orderStateModel = OrderState::where('flag', $orderStateFlag)->first();
  237. return $orderStateModel->id;
  238. }
  239. }