/includes/classes/Pay/Gateway/Abstract.php

  1. <?php 
  2.  
  3. abstract class Pay_Gateway_Abstract extends WC_Payment_Gateway 
  4. const STATUS_PENDING = 'pending'; 
  5. const STATUS_PROCESSING = 'processing'; 
  6. const STATUS_ON_HOLD = 'on-hold'; 
  7. const STATUS_COMPLETED = 'completed'; 
  8. const STATUS_CANCELLED = 'cancelled'; 
  9. const STATUS_REFUNDED = 'refunded'; 
  10. const STATUS_FAILED = 'failed'; 
  11.  
  12. public function __construct() 
  13. $this->id = $this->getId(); 
  14. $this->icon = $this->getIcon(); 
  15.  
  16. $this->has_fields = true; 
  17. $this->method_title = 'Pay.nl - ' . $this->getName(); 
  18. $this->method_description = sprintf(__('Activate this module to accept %s transactions',  
  19. PAYNL_WOOCOMMERCE_TEXTDOMAIN), $this->getName()); 
  20.  
  21. $this->supports = array('products', 'refunds'); 
  22.  
  23. $this->init_form_fields(); 
  24. $this->init_settings(); 
  25.  
  26. $this->title = $this->get_option('title'); 
  27. $this->description = $this->get_option('description'); 
  28.  
  29. add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); 
  30.  
  31. public static function getId() 
  32. throw new Exception('Please implement the getId method'); 
  33.  
  34. public function getIcon() 
  35. $size = get_option('paynl_logo_size'); 
  36.  
  37. if ($size) { 
  38. return 'https://www.pay.nl/images/payment_profiles/' . $size . '/' . $this->getOptionId() . '.png'; 
  39. } else { 
  40. return ''; 
  41.  
  42.  
  43. public static function getOptionId() 
  44. throw new Exception('Please implement the getOptionId method'); 
  45.  
  46. public static function getName() 
  47. throw new Exception('Please implement the getName method'); 
  48.  
  49. /** 
  50. * Initialise Gateway Settings Form Fields. 
  51. */ 
  52. public function init_form_fields() 
  53. $optionId = $this->getOptionId(); 
  54. if (Pay_Helper_Data::isOptionAvailable($optionId)) { 
  55. $this->form_fields = array( 
  56. 'enabled' => array( 
  57. 'title' => __('Enable/Disable', 'woocommerce'),  
  58. 'type' => 'checkbox',  
  59. 'label' => sprintf(__('Enable Pay.nl %s', PAYNL_WOOCOMMERCE_TEXTDOMAIN), $this->getName()),  
  60. 'default' => 'no',  
  61. ),  
  62. 'title' => array( 
  63. 'title' => __('Title', 'woocommerce'),  
  64. 'type' => 'text',  
  65. 'description' => __('This controls the title which the user sees during checkout.', 'woocommerce'),  
  66. 'default' => $this->getName(),  
  67. 'desc_tip' => true,  
  68. ),  
  69. 'description' => array( 
  70. 'title' => __('Customer Message', 'woocommerce'),  
  71. 'type' => 'textarea',  
  72. 'default' => sprintf(__('Pay with %s', PAYNL_WOOCOMMERCE_TEXTDOMAIN), $this->getName()),  
  73. ),  
  74. 'instructions' => array( 
  75. 'title' => __('Instructions', 'woocommerce'),  
  76. 'type' => 'textarea',  
  77. 'description' => __('Instructions that will be added to the thank you page.', 'woocommerce'),  
  78. 'default' => '',  
  79. 'desc_tip' => true,  
  80. ),  
  81. ); 
  82.  
  83. if ($this->slowConfirmation()) { 
  84. $this->form_fields['initial_order_status'] = array( 
  85. 'title' => __('Initial order status', PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  86. 'type' => 'select',  
  87. 'options' => array( 
  88. self::STATUS_ON_HOLD => wc_get_order_status_name(self::STATUS_ON_HOLD) . ' (' . __('default',  
  89. 'woocommerce') . ')',  
  90. self::STATUS_PENDING => wc_get_order_status_name(self::STATUS_PENDING),  
  91. ),  
  92. 'default' => self::STATUS_ON_HOLD,  
  93. /** translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */ 
  94. 'description' => sprintf( 
  95. __('Some payment methods take longer than a few hours to complete. The initial order state is then set to \'%s\'. This ensures the order is not cancelled when the setting %s is used.',  
  96. PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  97. wc_get_order_status_name(self::STATUS_ON_HOLD),  
  98. '<a href="' . admin_url('admin.php?page=wc-settings&tab=products§ion=inventory') . '" target="_blank">' . __('Hold Stock (minutes)',  
  99. 'woocommerce') . '</a>' 
  100. ),  
  101. ); 
  102.  
  103. } else { 
  104. $this->form_fields = array( 
  105. 'message' => array( 
  106. 'title' => __('Disabled', 'woocommerce'),  
  107. 'type' => 'hidden',  
  108. 'description' => __('This payment method is not available, please enable this in the pay.nl admin.',  
  109. PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  110. 'label' => sprintf(__('Enable Pay.nl %s', PAYNL_WOOCOMMERCE_TEXTDOMAIN), $this->getName()),  
  111.  
  112. ); 
  113.  
  114. /** 
  115. * @return bool Payment methods that are confirmed slowly (like banktransfer) should return true here 
  116. */ 
  117. public static function slowConfirmation() 
  118. return false; 
  119.  
  120. public function init_settings() 
  121. add_action('woocommerce_thankyou_' . $this->getId(), array($this, 'thankyou_page')); 
  122.  
  123. parent::init_settings(); 
  124.  
  125. public function payment_fields() 
  126. if ($description = $this->get_description()) { 
  127. echo wpautop(wptexturize($description)); 
  128.  
  129. public function process_payment($order_id) 
  130. /** @var $wpdb wpdb The database */ 
  131. $order = new WC_Order($order_id); 
  132.  
  133. $result = $this->startTransaction($order); 
  134.  
  135. $order->add_order_note(sprintf(__('Pay.nl: Transaction started: %s', PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  136. $result->getTransactionId())); 
  137.  
  138. if ($this->slowConfirmation()) { 
  139. $initial_status = $this->get_option('initial_order_status'); 
  140.  
  141. $order->update_status($initial_status, sprintf(__('Initial status set to %s ', PAYNL_WOOCOMMERCE_TEXTDOMAIN), wc_get_order_status_name($initial_status))); 
  142. if ($initial_status == self::STATUS_ON_HOLD) { 
  143. // Reduce stock levels 
  144. wc_reduce_stock_levels($order->get_id()); 
  145.  
  146. Pay_Helper_Transaction::newTransaction($result->getTransactionId(), $this->getOptionId(), $order->get_total(),  
  147. $order->get_id(), ''); 
  148.  
  149. // Return thankyou redirect 
  150. return array( 
  151. 'result' => 'success',  
  152. 'redirect' => $result->getRedirectUrl() 
  153. ); 
  154.  
  155. /** 
  156. * @param WC_Order $order 
  157. * @return \Paynl\Result\Transaction\Start 
  158. */ 
  159. protected function startTransaction(WC_Order $order) 
  160. $this->loginSDK(); 
  161.  
  162. $returnUrl = add_query_arg(array( 
  163. 'wc-api' => 'Wc_Pay_Gateway_Return',  
  164. 'utm_nooverride' => '1' 
  165. ), home_url('/')); 
  166.  
  167. $exchangeUrl = add_query_arg('wc-api', 'Wc_Pay_Gateway_Exchange', home_url('/')); 
  168.  
  169. if($order->get_customer_ip_address()) { 
  170. $ipAddress = $order->get_customer_ip_address(); 
  171. } else { 
  172. $ipAddress = Paynl\Helper::getIp(); 
  173.  
  174.  
  175. $startData = array( 
  176. 'amount' => $order->get_total(),  
  177. 'returnUrl' => $returnUrl,  
  178. 'exchangeUrl' => $exchangeUrl,  
  179. 'paymentMethod' => $this->getOptionId(),  
  180. 'currency' => $order->get_currency(),  
  181. 'description' => $order->get_order_number(),  
  182. 'extra1' => apply_filters( 'paynl-extra1', $order->get_order_number(), $order ),  
  183. 'extra2' => apply_filters( 'paynl-extra2', $order->get_billing_email(), $order ),  
  184. 'extra3' => apply_filters( 'paynl-extra3', $order->get_id(), $order ),  
  185. 'ipaddress' => $ipAddress 
  186. ); 
  187.  
  188. if (get_option('paynl_send_order_data') == 'yes') { 
  189. $enduser = array( 
  190. 'initials' => $order->get_shipping_first_name(),  
  191. 'lastName' => $order->get_shipping_last_name(),  
  192. 'phoneNumber' => $order->get_billing_phone(),  
  193. 'emailAddress' => $order->get_billing_email(),  
  194. ); 
  195. if ($_POST['birthdate']) { 
  196. $enduser['birthDate'] = $_POST['birthdate']; 
  197. $startData['enduser'] = $enduser; 
  198.  
  199.  
  200. // order gegevens ophalen 
  201. $shippingAddress = $order->get_shipping_address_1() . ' ' . $order->get_shipping_address_2(); 
  202. $aShippingAddress = \Paynl\Helper::splitAddress($shippingAddress); 
  203.  
  204. $address = array( 
  205. 'streetName' => $aShippingAddress[0],  
  206. 'houseNumber' => $aShippingAddress[1],  
  207. 'zipCode' => $order->get_shipping_postcode(),  
  208. 'city' => $order->get_shipping_city(),  
  209. 'country' => $order->get_shipping_country() 
  210. ); 
  211. $startData['address'] = $address; 
  212.  
  213. $billingAddress = $order->get_billing_address_1() . ' ' . $order->get_billing_address_2(); 
  214. $aBillingAddress = \Paynl\Helper::splitAddress($billingAddress); 
  215.  
  216. $invoiceAddress = array( 
  217. 'initials' => $order->get_billing_first_name(),  
  218. 'lastName' => $order->get_billing_last_name(),  
  219. 'streetName' => $aBillingAddress[0],  
  220. 'houseNumber' => $aBillingAddress[1],  
  221. 'zipCode' => $order->get_billing_postcode(),  
  222. 'city' => $order->get_billing_city(),  
  223. 'country' => $order->get_billing_country() 
  224. ); 
  225. $startData['invoiceAddress'] = $invoiceAddress; 
  226. $startData['products'] = $this->getProductLines($order); 
  227.  
  228. if (isset($_POST['option_sub_id']) && !empty($_POST['option_sub_id'])) { 
  229. $startData['bank'] = $_POST['option_sub_id']; 
  230. if (get_option('paynl_test_mode') == 'yes') { 
  231. $startData['testmode'] = true; 
  232. $language = get_option('paynl_language'); 
  233.  
  234. if ($language == 'browser') { 
  235. $language = Pay_Helper_Data::getBrowserLanguage(); 
  236. $startData['language'] = $language; 
  237.  
  238. $result = \Paynl\Transaction::start($startData); 
  239.  
  240. return $result; 
  241.  
  242. public static function loginSDK() 
  243. \Paynl\Config::setApiToken(self::getApiToken()); 
  244. \Paynl\Config::setServiceId(self::getServiceId()); 
  245.  
  246. $verifyPeer = (get_option('paynl_verify_peer') == 'yes'); 
  247. \Paynl\Config::setVerifyPeer($verifyPeer); 
  248.  
  249. public static function getApiToken() 
  250. return get_option('paynl_apitoken'); 
  251.  
  252. public static function getServiceId() 
  253. return get_option('paynl_serviceid'); 
  254.  
  255. private function getProductLines(WC_Order $order) 
  256. $items = $order->get_items(); 
  257.  
  258. $aProducts = array(); 
  259.  
  260. foreach ($items as $item) { 
  261. $pricePerPiece = ($item['line_subtotal'] + $item['line_subtotal_tax']) / $item['qty']; 
  262. $taxPerPiece = $item['line_subtotal_tax'] / $item['qty']; 
  263. $product = array( 
  264. 'id' => $item['product_id'],  
  265. 'name' => $item['name'],  
  266. 'price' => $pricePerPiece,  
  267. 'qty' => $item['qty'],  
  268. 'type' => \Paynl\Transaction::PRODUCT_TYPE_ARTICLE,  
  269. 'tax' => $taxPerPiece 
  270. ); 
  271. $aProducts[] = $product; 
  272. // verzendkosten meesturen 
  273. $shipping = floatval($order->get_shipping_total()) + floatval($order->get_shipping_tax()); 
  274. if ($shipping != 0) { 
  275. $aProducts[] = array( 
  276. 'id' => 'shipping',  
  277. 'name' => __('Shipping', PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  278. 'price' => $shipping,  
  279. 'tax' => $order->get_shipping_tax(),  
  280. 'qty' => 1,  
  281. 'type' => \Paynl\Transaction::PRODUCT_TYPE_SHIPPING 
  282. ); 
  283.  
  284. //korting meesturen 
  285. $discount = $order->get_total_discount(false); 
  286. if ($discount != 0) { 
  287. $discountExcl = $order->get_total_discount(true); 
  288. $discountTax = $discount - $discountExcl; 
  289.  
  290. $aProducts[] = array( 
  291. 'id' => 'discount',  
  292. 'name' => __('Discount', PAYNL_WOOCOMMERCE_TEXTDOMAIN),  
  293. 'price' => $discount * -1,  
  294. 'qty' => 1,  
  295. 'type' => \Paynl\Transaction::PRODUCT_TYPE_DISCOUNT,  
  296. 'tax' => $discountTax * -1 
  297. ); 
  298.  
  299. //fees meesturen 
  300. //Extra kosten meesturen 
  301. $fees = $order->get_fees(); 
  302. if (!empty($fees)) { 
  303. foreach ($fees as $fee) { 
  304. $aProducts[] = array( 
  305. 'id' => $fee['type'],  
  306. 'name' => $fee['name'],  
  307. 'price' => $fee['line_total'],  
  308. 'qty' => 1,  
  309. 'type' => \Paynl\Transaction::PRODUCT_TYPE_HANDLING 
  310. ); 
  311.  
  312. return $aProducts; 
  313.  
  314. /** 
  315. * Process a refund if supported 
  316. * @param int $order_id 
  317. * @param float $amount 
  318. * @param string $reason 
  319. * @return bool|wp_error True or false based on success, or a WP_Error object 
  320. */ 
  321. public function process_refund($order_id, $amount = null, $reason = '') 
  322. $order = wc_get_order($order_id); 
  323.  
  324. $transactionId = Pay_Helper_Transaction::getPaidTransactionIdForOrderId($order_id); 
  325.  
  326. if (!$order || !$transactionId) { 
  327. return false; 
  328.  
  329. try { 
  330. $this->loginSDK(); 
  331.  
  332. $result = \Paynl\Transaction::refund($transactionId, $amount, $reason); 
  333.  
  334. $order->add_order_note(sprintf(__('Refunded %s - Refund ID: %s', PAYNL_WOOCOMMERCE_TEXTDOMAIN), $amount,  
  335. $result->getRefundId())); 
  336. return true; 
  337. } catch (Exception $e) { 
  338. return new WP_Error(1, $e->getMessage()); 
  339.  
  340. /** 
  341. * Output for the order received page. 
  342. */ 
  343. public function thankyou_page() 
  344. if ($this->get_option('instructions')) { 
  345. echo wpautop(wptexturize($this->get_option('instructions'))); 
  346.  
.