WC_Gateway_Simplify_Commerce

Simplify Commerce Gateway.

Defined (1)

The class is defined in the following location(s).

/includes/gateways/simplify-commerce/class-wc-gateway-simplify-commerce.php  
  1. class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway_CC { 
  2.  
  3. /** 
  4. * Constructor. 
  5. */ 
  6. public function __construct() { 
  7. $this->id = 'simplify_commerce'; 
  8. $this->method_title = __( 'Simplify Commerce', 'woocommerce' ); 
  9. $this->method_description = __( 'Take payments via Simplify Commerce - uses simplify.js to create card tokens and the Simplify Commerce SDK. Requires SSL when sandbox is disabled.', 'woocommerce' ); 
  10. $this->new_method_label = __( 'Use a new card', 'woocommerce' ); 
  11. $this->has_fields = true; 
  12. $this->supports = array( 
  13. 'subscriptions',  
  14. 'products',  
  15. 'subscription_cancellation',  
  16. 'subscription_reactivation',  
  17. 'subscription_suspension',  
  18. 'subscription_amount_changes',  
  19. 'subscription_payment_method_change', // Subscriptions 1.n compatibility 
  20. 'subscription_payment_method_change_customer',  
  21. 'subscription_payment_method_change_admin',  
  22. 'subscription_date_changes',  
  23. 'multiple_subscriptions',  
  24. 'default_credit_card_form',  
  25. 'tokenization',  
  26. 'refunds',  
  27. 'pre-orders',  
  28. ); 
  29. $this->view_transaction_url = 'https://www.simplify.com/commerce/app#/payment/%s'; 
  30.  
  31. // Load the form fields 
  32. $this->init_form_fields(); 
  33.  
  34. // Load the settings. 
  35. $this->init_settings(); 
  36.  
  37. // Get setting values 
  38. $this->title = $this->get_option( 'title' ); 
  39. $this->description = $this->get_option( 'description' ); 
  40. $this->enabled = $this->get_option( 'enabled' ); 
  41. $this->mode = $this->get_option( 'mode', 'standard' ); 
  42. $this->modal_color = $this->get_option( 'modal_color', '#a46497' ); 
  43. $this->sandbox = $this->get_option( 'sandbox' ); 
  44. $this->public_key = ( 'no' === $this->sandbox ) ? $this->get_option( 'public_key' ) : $this->get_option( 'sandbox_public_key' ); 
  45. $this->private_key = ( 'no' === $this->sandbox ) ? $this->get_option( 'private_key' ) : $this->get_option( 'sandbox_private_key' ); 
  46.  
  47. $this->init_simplify_sdk(); 
  48.  
  49. // Hooks 
  50. add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) ); 
  51. add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); 
  52. add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) ); 
  53. add_action( 'woocommerce_api_wc_gateway_simplify_commerce', array( $this, 'return_handler' ) ); 
  54.  
  55. /** 
  56. * Init Simplify SDK. 
  57. */ 
  58. protected function init_simplify_sdk() { 
  59. // Include lib 
  60. require_once( dirname( __FILE__ ) . '/includes/Simplify.php' ); 
  61.  
  62. Simplify::$publicKey = $this->public_key; 
  63. Simplify::$privateKey = $this->private_key; 
  64. Simplify::$userAgent = 'WooCommerce/' . WC()->version; 
  65.  
  66. /** 
  67. * Admin Panel Options. 
  68. * - Options for bits like 'title' and availability on a country-by-country basis. 
  69. */ 
  70. public function admin_options() { 
  71. ?> 
  72. <h3><?php _e( 'Simplify Commerce by MasterCard', 'woocommerce' ); ?></h3> 
  73.  
  74. <?php if ( empty( $this->public_key ) ) : ?> 
  75. <div class="simplify-commerce-banner updated"> 
  76. <img src="<?php echo WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/images/logo.png'; ?>" /> 
  77. <p class="main"><strong><?php _e( 'Getting started', 'woocommerce' ); ?></strong></p> 
  78. <p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p> 
  79.  
  80. <p><a href="https://www.simplify.com/commerce/partners/woocommerce#/signup" target="_blank" class="button button-primary"><?php _e( 'Sign up for Simplify Commerce', 'woocommerce' ); ?></a> <a href="https://www.simplify.com/commerce/partners/woocommerce#/" target="_blank" class="button"><?php _e( 'Learn more', 'woocommerce' ); ?></a></p> 
  81.  
  82. </div> 
  83. <?php else : ?> 
  84. <p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p> 
  85. <?php endif; ?> 
  86.  
  87. <?php $this->checks(); ?> 
  88.  
  89. <table class="form-table"> 
  90. <?php $this->generate_settings_html(); ?> 
  91. <script type="text/javascript"> 
  92. jQuery( '#woocommerce_simplify_commerce_sandbox' ).on( 'change', function() { 
  93. var sandbox = jQuery( '#woocommerce_simplify_commerce_sandbox_public_key, #woocommerce_simplify_commerce_sandbox_private_key' ).closest( 'tr' ),  
  94. production = jQuery( '#woocommerce_simplify_commerce_public_key, #woocommerce_simplify_commerce_private_key' ).closest( 'tr' ); 
  95.  
  96. if ( jQuery( this ).is( ':checked' ) ) { 
  97. sandbox.show(); 
  98. production.hide(); 
  99. } else { 
  100. sandbox.hide(); 
  101. production.show(); 
  102. }).change(); 
  103.  
  104. jQuery( '#woocommerce_simplify_commerce_mode' ).on( 'change', function() { 
  105. var color = jQuery( '#woocommerce_simplify_commerce_modal_color' ).closest( 'tr' ); 
  106.  
  107. if ( 'standard' === jQuery( this ).val() ) { 
  108. color.hide(); 
  109. } else { 
  110. color.show(); 
  111. }).change(); 
  112. </script> 
  113. </table> 
  114. <?php 
  115.  
  116. /** 
  117. * Check if SSL is enabled and notify the user. 
  118. */ 
  119. public function checks() { 
  120. if ( 'no' == $this->enabled ) { 
  121. return; 
  122.  
  123. if ( version_compare( phpversion(), '5.3', '<' ) ) { 
  124.  
  125. // PHP Version 
  126. echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce Error: Simplify commerce requires PHP 5.3 and above. You are using version %s.', 'woocommerce' ), phpversion() ) . '</p></div>'; 
  127.  
  128. } elseif ( ! $this->public_key || ! $this->private_key ) { 
  129.  
  130. // Check required fields 
  131. echo '<div class="error"><p>' . __( 'Simplify Commerce Error: Please enter your public and private keys', 'woocommerce' ) . '</p></div>'; 
  132.  
  133. } elseif ( 'standard' == $this->mode && ! wc_checkout_is_https() ) { 
  134.  
  135. // Show message when using standard mode and no SSL on the checkout page 
  136. echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce is enabled, but the <a href="%s">force SSL option</a> is disabled; your checkout may not be secure! Please enable SSL and ensure your server has a valid SSL certificate - Simplify Commerce will only work in sandbox mode.', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ) . '</p></div>'; 
  137.  
  138.  
  139. /** 
  140. * Check if this gateway is enabled. 
  141. * @return bool 
  142. */ 
  143. public function is_available() { 
  144. if ( 'yes' !== $this->enabled ) { 
  145. return false; 
  146.  
  147. if ( 'standard' === $this->mode && 'yes' !== $this->sandbox && ! wc_checkout_is_https() ) { 
  148. return false; 
  149.  
  150. if ( ! $this->public_key || ! $this->private_key ) { 
  151. return false; 
  152.  
  153. return true; 
  154.  
  155. /** 
  156. * Initialise Gateway Settings Form Fields. 
  157. */ 
  158. public function init_form_fields() { 
  159. $this->form_fields = array( 
  160. 'enabled' => array( 
  161. 'title' => __( 'Enable/Disable', 'woocommerce' ),  
  162. 'label' => __( 'Enable Simplify Commerce', 'woocommerce' ),  
  163. 'type' => 'checkbox',  
  164. 'description' => '',  
  165. 'default' => 'no',  
  166. ),  
  167. 'title' => array( 
  168. 'title' => __( 'Title', 'woocommerce' ),  
  169. 'type' => 'text',  
  170. 'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),  
  171. 'default' => __( 'Credit card', 'woocommerce' ),  
  172. 'desc_tip' => true,  
  173. ),  
  174. 'description' => array( 
  175. 'title' => __( 'Description', 'woocommerce' ),  
  176. 'type' => 'text',  
  177. 'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ),  
  178. 'default' => 'Pay with your credit card via Simplify Commerce by MasterCard.',  
  179. 'desc_tip' => true,  
  180. ),  
  181. 'mode' => array( 
  182. 'title' => __( 'Payment mode', 'woocommerce' ),  
  183. 'label' => __( 'Enable Hosted Payments', 'woocommerce' ),  
  184. 'type' => 'select',  
  185. 'description' => sprintf( __( 'Standard will display the credit card fields on your store (SSL required). %1$s Hosted Payments will display a Simplify Commerce modal dialog on your store (if SSL) or will redirect the customer to Simplify Commerce hosted page (if not SSL). %1$s Note: Hosted Payments need a new API Key pair with the hosted payments flag selected. %2$sFor more details check the Simplify Commerce docs%3$s.', 'woocommerce' ), '<br />', '<a href="https://simplify.desk.com/customer/portal/articles/1792405-how-do-i-enable-hosted-payments" target="_blank">', '</a>' ),  
  186. 'default' => 'standard',  
  187. 'options' => array( 
  188. 'standard' => __( 'Standard', 'woocommerce' ),  
  189. 'hosted' => __( 'Hosted Payments', 'woocommerce' ),  
  190. ),  
  191. ),  
  192. 'modal_color' => array( 
  193. 'title' => __( 'Modal color', 'woocommerce' ),  
  194. 'type' => 'color',  
  195. 'description' => __( 'Set the color of the buttons and titles on the modal dialog.', 'woocommerce' ),  
  196. 'default' => '#a46497',  
  197. 'desc_tip' => true,  
  198. ),  
  199. 'sandbox' => array( 
  200. 'title' => __( 'Sandbox', 'woocommerce' ),  
  201. 'label' => __( 'Enable sandbox mode', 'woocommerce' ),  
  202. 'type' => 'checkbox',  
  203. 'description' => __( 'Place the payment gateway in sandbox mode using sandbox API keys (real payments will not be taken).', 'woocommerce' ),  
  204. 'default' => 'yes',  
  205. ),  
  206. 'sandbox_public_key' => array( 
  207. 'title' => __( 'Sandbox public key', 'woocommerce' ),  
  208. 'type' => 'text',  
  209. 'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),  
  210. 'default' => '',  
  211. 'desc_tip' => true,  
  212. ),  
  213. 'sandbox_private_key' => array( 
  214. 'title' => __( 'Sandbox private key', 'woocommerce' ),  
  215. 'type' => 'text',  
  216. 'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),  
  217. 'default' => '',  
  218. 'desc_tip' => true,  
  219. ),  
  220. 'public_key' => array( 
  221. 'title' => __( 'Public key', 'woocommerce' ),  
  222. 'type' => 'text',  
  223. 'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),  
  224. 'default' => '',  
  225. 'desc_tip' => true,  
  226. ),  
  227. 'private_key' => array( 
  228. 'title' => __( 'Private key', 'woocommerce' ),  
  229. 'type' => 'text',  
  230. 'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ),  
  231. 'default' => '',  
  232. 'desc_tip' => true,  
  233. ),  
  234. ); 
  235.  
  236. /** 
  237. * Payment form on checkout page. 
  238. */ 
  239. public function payment_fields() { 
  240. $description = $this->get_description(); 
  241.  
  242. if ( 'yes' == $this->sandbox ) { 
  243. $description .= ' ' . sprintf( __( 'TEST MODE ENABLED. Use a test card: %s', 'woocommerce' ), '<a href="https://www.simplify.com/commerce/docs/tutorial/index#testing">https://www.simplify.com/commerce/docs/tutorial/index#testing</a>' ); 
  244.  
  245. if ( $description ) { 
  246. echo wpautop( wptexturize( trim( $description ) ) ); 
  247.  
  248. if ( 'standard' == $this->mode ) { 
  249. parent::payment_fields(); 
  250.  
  251. /** 
  252. * Outputs scripts used for simplify payment. 
  253. */ 
  254. public function payment_scripts() { 
  255. $load_scripts = false; 
  256.  
  257. if ( is_checkout() ) { 
  258. $load_scripts = true; 
  259. if ( $this->is_available() ) { 
  260. $load_scripts = true; 
  261.  
  262. if ( false === $load_scripts ) { 
  263. return; 
  264.  
  265. wp_enqueue_script( 'simplify-commerce', 'https://www.simplify.com/commerce/v1/simplify.js', array( 'jquery' ), WC_VERSION, true ); 
  266. wp_enqueue_script( 'wc-simplify-commerce', WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/js/simplify-commerce.js', array( 'simplify-commerce', 'wc-credit-card-form' ), WC_VERSION, true ); 
  267. wp_localize_script( 'wc-simplify-commerce', 'Simplify_commerce_params', array( 
  268. 'key' => $this->public_key,  
  269. 'card.number' => __( 'Card number', 'woocommerce' ),  
  270. 'card.expMonth' => __( 'Expiry month', 'woocommerce' ),  
  271. 'card.expYear' => __( 'Expiry year', 'woocommerce' ),  
  272. 'is_invalid' => __( 'is invalid', 'woocommerce' ),  
  273. 'mode' => $this->mode,  
  274. 'is_ssl' => is_ssl(),  
  275. ) ); 
  276.  
  277. public function add_payment_method() { 
  278. if ( empty( $_POST['simplify_token'] ) ) { 
  279. wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' ); 
  280. return; 
  281.  
  282. $cart_token = wc_clean( $_POST['simplify_token'] ); 
  283. $customer_token = $this->get_users_token(); 
  284. $current_user = wp_get_current_user(); 
  285. $customer_info = array( 
  286. 'email' => $current_user->user_email,  
  287. 'name' => $current_user->display_name,  
  288. ); 
  289.  
  290. $token = $this->save_token( $customer_token, $cart_token, $customer_info ); 
  291. if ( is_null( $token ) ) { 
  292. wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' ); 
  293. return; 
  294.  
  295. return array( 
  296. 'result' => 'success',  
  297. 'redirect' => wc_get_endpoint_url( 'payment-methods' ),  
  298. ); 
  299.  
  300. /** 
  301. * Actually saves a customer token to the database. 
  302. * @param WC_Payment_Token $customer_token Payment Token 
  303. * @param string $cart_token CC Token 
  304. * @param array $customer_info 'email', 'name' 
  305. */ 
  306. public function save_token( $customer_token, $cart_token, $customer_info ) { 
  307. if ( ! is_null( $customer_token ) ) { 
  308. $customer = Simplify_Customer::findCustomer( $customer_token->get_token() ); 
  309. $updates = array( 'token' => $cart_token ); 
  310. $customer->setAll( $updates ); 
  311. $customer->updateCustomer(); 
  312. $customer = Simplify_Customer::findCustomer( $customer_token->get_token() ); // get updated customer with new set card 
  313. $token = $customer_token; 
  314. } else { 
  315. $customer = Simplify_Customer::createCustomer( array( 
  316. 'token' => $cart_token,  
  317. 'email' => $customer_info['email'],  
  318. 'name' => $customer_info['name'],  
  319. ) ); 
  320. $token = new WC_Payment_Token_CC(); 
  321. $token->set_token( $customer->id ); 
  322.  
  323. // If we were able to create an save our card, save the data on our side too 
  324. if ( is_object( $customer ) && '' != $customer->id ) { 
  325. $customer_properties = $customer->getProperties(); 
  326. $card = $customer_properties['card']; 
  327. $token->set_gateway_id( $this->id ); 
  328. $token->set_card_type( strtolower( $card->type ) ); 
  329. $token->set_last4( $card->last4 ); 
  330. $expiry_month = ( 1 === strlen( $card->expMonth ) ? '0' . $card->expMonth : $card->expMonth ); 
  331. $token->set_expiry_month( $expiry_month ); 
  332. $token->set_expiry_year( '20' . $card->expYear ); 
  333. if ( is_user_logged_in() ) { 
  334. $token->set_user_id( get_current_user_id() ); 
  335. $token->save(); 
  336. return $token; 
  337.  
  338. return null; 
  339.  
  340. /** 
  341. * Process customer: updating or creating a new customer/saved CC 
  342. * @param WC_Order $order Order object 
  343. * @param WC_Payment_Token $customer_token Payment Token 
  344. * @param string $cart_token CC Token 
  345. */ 
  346. protected function process_customer( $order, $customer_token = null, $cart_token = '' ) { 
  347. // Are we saving a new payment method? 
  348. if ( is_user_logged_in() && isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) { 
  349. $customer_info = array( 
  350. 'email' => $order->get_billing_email(),  
  351. 'name' => trim( $order->get_formatted_billing_full_name() ),  
  352. ); 
  353. $token = $this->save_token( $customer_token, $cart_token, $customer_info ); 
  354. if ( ! is_null( $token ) ) { 
  355. $order->add_payment_token( $token ); 
  356.  
  357. /** 
  358. * Process standard payments. 
  359. * @param WC_Order $order 
  360. * @param string $cart_token 
  361. * @uses Simplify_ApiException 
  362. * @uses Simplify_BadRequestException 
  363. * @return array 
  364. */ 
  365. protected function process_standard_payments( $order, $cart_token = '', $customer_token = '' ) { 
  366. try { 
  367.  
  368. if ( empty( $cart_token ) && empty( $customer_token ) ) { 
  369. $error_msg = __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' ); 
  370.  
  371. if ( 'yes' == $this->sandbox ) { 
  372. $error_msg .= ' ' . __( 'Developers: Please make sure that you\'re including jQuery and there are no JavaScript errors on the page.', 'woocommerce' ); 
  373.  
  374. throw new Simplify_ApiException( $error_msg ); 
  375.  
  376. // We need to figure out if we want to charge the card token (new unsaved token, no customer, etc) 
  377. // or the customer token (just saved method, previously saved method) 
  378. $pass_tokens = array(); 
  379.  
  380. if ( ! empty( $cart_token ) ) { 
  381. $pass_tokens['token'] = $cart_token; 
  382.  
  383. if ( ! empty( $customer_token ) ) { 
  384. $pass_tokens['customer'] = $customer_token; 
  385. // Use the customer token only, since we already saved the (one time use) card token to the customer 
  386. if ( isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) { 
  387. unset( $pass_tokens['token'] ); 
  388.  
  389. // Did we create an account and save a payment method? We might need to use the customer token instead of the card token 
  390. if ( isset( $_POST['createaccount'] ) && true === (bool) $_POST['createaccount'] && empty( $customer_token ) ) { 
  391. $user_token = $this->get_users_token(); 
  392. if ( ! is_null( $user_token ) ) { 
  393. $pass_tokens['customer'] = $user_token->get_token(); 
  394. unset( $pass_tokens['token'] ); 
  395.  
  396. $payment_response = $this->do_payment( $order, $order->get_total(), $pass_tokens ); 
  397.  
  398. if ( is_wp_error( $payment_response ) ) { 
  399. throw new Simplify_ApiException( $payment_response->get_error_message() ); 
  400. } else { 
  401. // Remove cart 
  402. WC()->cart->empty_cart(); 
  403.  
  404. // Return thank you page redirect 
  405. return array( 
  406. 'result' => 'success',  
  407. 'redirect' => $this->get_return_url( $order ),  
  408. ); 
  409. } catch ( Simplify_ApiException $e ) { 
  410. if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { 
  411. foreach ( $e->getFieldErrors() as $error ) { 
  412. wc_add_notice( $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error' ); 
  413. } else { 
  414. wc_add_notice( $e->getMessage(), 'error' ); 
  415.  
  416. return array( 
  417. 'result' => 'fail',  
  418. 'redirect' => '',  
  419. ); 
  420.  
  421. /** 
  422. * do payment function. 
  423. * @param WC_order $order 
  424. * @param int $amount (default: 0) 
  425. * @uses Simplify_BadRequestException 
  426. * @return bool|WP_Error 
  427. */ 
  428. public function do_payment( $order, $amount = 0, $token = array() ) { 
  429. if ( $amount * 100 < 50 ) { 
  430. return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) ); 
  431.  
  432. try { 
  433. // Charge the customer 
  434. $data = array( 
  435. 'amount' => $amount * 100, // In cents. 
  436. 'description' => sprintf( __( '%1$s - Order #%2$s', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order->get_order_number() ),  
  437. 'currency' => strtoupper( get_woocommerce_currency() ),  
  438. 'reference' => $order->get_id(),  
  439. ); 
  440.  
  441. $data = array_merge( $data, $token ); 
  442. $payment = Simplify_Payment::createPayment( $data ); 
  443.  
  444. } catch ( Exception $e ) { 
  445.  
  446. $error_message = $e->getMessage(); 
  447.  
  448. if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { 
  449. $error_message = ''; 
  450. foreach ( $e->getFieldErrors() as $error ) { 
  451. $error_message .= ' ' . $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')'; 
  452.  
  453. $order->add_order_note( sprintf( __( 'Simplify payment error: %s.', 'woocommerce' ), $error_message ) ); 
  454.  
  455. return new WP_Error( 'simplify_payment_declined', $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  456.  
  457. if ( 'APPROVED' == $payment->paymentStatus ) { 
  458. // Payment complete 
  459. $order->payment_complete( $payment->id ); 
  460.  
  461. // Add order note 
  462. $order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment->id, $payment->authCode ) ); 
  463.  
  464. return true; 
  465. } else { 
  466. $order->add_order_note( __( 'Simplify payment declined', 'woocommerce' ) ); 
  467.  
  468. return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - please try another card.', 'woocommerce' ) ); 
  469.  
  470. /** 
  471. * Process standard payments. 
  472. * @param WC_Order $order 
  473. * @return array 
  474. */ 
  475. protected function process_hosted_payments( $order ) { 
  476. return array( 
  477. 'result' => 'success',  
  478. 'redirect' => $order->get_checkout_payment_url( true ),  
  479. ); 
  480.  
  481. protected function get_users_token() { 
  482. $customer_token = null; 
  483. if ( is_user_logged_in() ) { 
  484. $tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() ); 
  485. foreach ( $tokens as $token ) { 
  486. if ( $token->get_gateway_id() === $this->id ) { 
  487. $customer_token = $token; 
  488. break; 
  489. return $customer_token; 
  490.  
  491. /** 
  492. * Process the payment. 
  493. * @param int $order_id 
  494. */ 
  495. public function process_payment( $order_id ) { 
  496. $order = wc_get_order( $order_id ); 
  497.  
  498. // Payment/CC form is hosted on Simplify 
  499. if ( 'hosted' === $this->mode ) { 
  500. return $this->process_hosted_payments( $order ); 
  501.  
  502. // New CC info was entered 
  503. if ( isset( $_POST['simplify_token'] ) ) { 
  504. $cart_token = wc_clean( $_POST['simplify_token'] ); 
  505. $customer_token = $this->get_users_token(); 
  506. $customer_token_value = ( ! is_null( $customer_token ) ? $customer_token->get_token() : '' ); 
  507. $this->process_customer( $order, $customer_token, $cart_token ); 
  508. return $this->process_standard_payments( $order, $cart_token, $customer_token_value ); 
  509.  
  510. // Possibly Create (or update) customer/save payment token, use an existing token, and then process the payment 
  511. if ( isset( $_POST['wc-simplify_commerce-payment-token'] ) && 'new' !== $_POST['wc-simplify_commerce-payment-token'] ) { 
  512. $token_id = wc_clean( $_POST['wc-simplify_commerce-payment-token'] ); 
  513. $token = WC_Payment_Tokens::get( $token_id ); 
  514. if ( $token->get_user_id() !== get_current_user_id() ) { 
  515. wc_add_notice( __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' ), 'error' ); 
  516. return; 
  517. $this->process_customer( $order, $token ); 
  518. return $this->process_standard_payments( $order, '', $token->get_token() ); 
  519.  
  520. /** 
  521. * Hosted payment args. 
  522. * @param WC_Order $order 
  523. * @return array 
  524. */ 
  525. protected function get_hosted_payments_args( $order ) { 
  526. $args = apply_filters( 'woocommerce_simplify_commerce_hosted_args', array( 
  527. 'sc-key' => $this->public_key,  
  528. 'amount' => $order->get_total() * 100,  
  529. 'reference' => $order->get_id(),  
  530. 'name' => esc_html( get_bloginfo( 'name', 'display' ) ),  
  531. 'description' => sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ),  
  532. 'receipt' => 'false',  
  533. 'color' => $this->modal_color,  
  534. 'redirect-url' => WC()->api_request_url( 'WC_Gateway_Simplify_Commerce' ),  
  535. 'address' => $order->get_billing_address_1() . ' ' . $order->get_billing_address_2(),  
  536. 'address-city' => $order->get_billing_city(),  
  537. 'address-state' => $order->get_billing_state(),  
  538. 'address-zip' => $order->get_billing_postcode(),  
  539. 'address-country' => $order->get_billing_country(),  
  540. 'operation' => 'create.token',  
  541. ), $order->get_id() ); 
  542.  
  543. return $args; 
  544.  
  545. /** 
  546. * Receipt page. 
  547. * @param int $order_id 
  548. */ 
  549. public function receipt_page( $order_id ) { 
  550. $order = wc_get_order( $order_id ); 
  551.  
  552. echo '<p>' . __( 'Thank you for your order, please click the button below to pay with credit card using Simplify Commerce by MasterCard.', 'woocommerce' ) . '</p>'; 
  553.  
  554. $args = $this->get_hosted_payments_args( $order ); 
  555. $button_args = array(); 
  556. foreach ( $args as $key => $value ) { 
  557. $button_args[] = 'data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; 
  558.  
  559. echo '<script type="text/javascript" src="https://www.simplify.com/commerce/simplify.pay.js"></script> 
  560. <button class="button alt" id="simplify-payment-button" ' . implode( ' ', $button_args ) . '>' . __( 'Pay now', 'woocommerce' ) . '</button> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order & restore cart', 'woocommerce' ) . '</a> 
  561. '; 
  562.  
  563. /** 
  564. * Return handler for Hosted Payments. 
  565. */ 
  566. public function return_handler() { 
  567. @ob_clean(); 
  568. header( 'HTTP/1.1 200 OK' ); 
  569.  
  570. if ( isset( $_REQUEST['reference'] ) && isset( $_REQUEST['paymentId'] ) && isset( $_REQUEST['signature'] ) ) { 
  571. $signature = strtoupper( md5( $_REQUEST['amount'] . $_REQUEST['reference'] . $_REQUEST['paymentId'] . $_REQUEST['paymentDate'] . $_REQUEST['paymentStatus'] . $this->private_key ) ); 
  572. $order_id = absint( $_REQUEST['reference'] ); 
  573. $order = wc_get_order( $order_id ); 
  574.  
  575. if ( $signature === $_REQUEST['signature'] ) { 
  576. $order_complete = $this->process_order_status( $order, $_REQUEST['paymentId'], $_REQUEST['paymentStatus'], $_REQUEST['paymentDate'] ); 
  577.  
  578. if ( ! $order_complete ) { 
  579. $order->update_status( 'failed', __( 'Payment was declined by Simplify Commerce.', 'woocommerce' ) ); 
  580.  
  581. wp_redirect( $this->get_return_url( $order ) ); 
  582. exit(); 
  583.  
  584. wp_redirect( wc_get_page_permalink( 'cart' ) ); 
  585. exit(); 
  586.  
  587. /** 
  588. * Process the order status. 
  589. * @param WC_Order $order 
  590. * @param string $payment_id 
  591. * @param string $status 
  592. * @param string $auth_code 
  593. * @return bool 
  594. */ 
  595. public function process_order_status( $order, $payment_id, $status, $auth_code ) { 
  596. if ( 'APPROVED' == $status ) { 
  597. // Payment complete 
  598. $order->payment_complete( $payment_id ); 
  599.  
  600. // Add order note 
  601. $order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %1$s, Auth Code: %2$s)', 'woocommerce' ), $payment_id, $auth_code ) ); 
  602.  
  603. // Remove cart 
  604. WC()->cart->empty_cart(); 
  605.  
  606. return true; 
  607.  
  608. return false; 
  609.  
  610. /** 
  611. * Process refunds. 
  612. * WooCommerce 2.2 or later. 
  613. * @param int $order_id 
  614. * @param float $amount 
  615. * @param string $reason 
  616. * @uses Simplify_ApiException 
  617. * @uses Simplify_BadRequestException 
  618. * @return bool|WP_Error 
  619. */ 
  620. public function process_refund( $order_id, $amount = null, $reason = '' ) { 
  621. try { 
  622. $payment_id = get_post_meta( $order_id, '_transaction_id', true ); 
  623.  
  624. $refund = Simplify_Refund::createRefund( array( 
  625. 'amount' => $amount * 100, // In cents. 
  626. 'payment' => $payment_id,  
  627. 'reason' => $reason,  
  628. 'reference' => $order_id,  
  629. ) ); 
  630.  
  631. if ( 'APPROVED' == $refund->paymentStatus ) { 
  632. return true; 
  633. } else { 
  634. throw new Simplify_ApiException( __( 'Refund was declined.', 'woocommerce' ) ); 
  635. } catch ( Simplify_ApiException $e ) { 
  636. if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { 
  637. foreach ( $e->getFieldErrors() as $error ) { 
  638. return new WP_Error( 'simplify_refund_error', $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')' ); 
  639. } else { 
  640. return new WP_Error( 'simplify_refund_error', $e->getMessage() ); 
  641.  
  642. return false; 
  643.  
  644. /** 
  645. * Get gateway icon. 
  646. * @access public 
  647. * @return string 
  648. */ 
  649. public function get_icon() { 
  650. $icon = '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/visa.svg' ) . '" alt="Visa" width="32" />'; 
  651. $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/mastercard.svg' ) . '" alt="MasterCard" width="32" />'; 
  652. $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/discover.svg' ) . '" alt="Discover" width="32" />'; 
  653. $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/amex.svg' ) . '" alt="Amex" width="32" />'; 
  654. $icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/jcb.svg' ) . '" alt="JCB" width="32" />'; 
  655.  
  656. return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id );