/** * Conditionally adds the payment token fields to the Admin User Edit * screen, if tokenization is enabled on the gateway, and the gateway * API does not support payment token retrieval (meaning the tokens * are stored only locally) * * @see SV_WC_Payment_Gateway_Admin_User_Edit_Handler::save_user_profile_tokenization_fields() * @param SV_WC_Payment_Gateway $gateway the gateway instance * @param WP_User $user user object for the current edit page */ protected function maybe_add_user_profile_tokenization_fields($gateway, $user) { // ensure that it supports tokenization, but doesn't have a "get tokens" request, meaning that the tokens are stored and accessed locally if ($gateway->tokenization_enabled() && !$gateway->get_api()->supports_get_tokenized_payment_methods()) { $environments = $gateway->get_environments(); foreach ($environments as $environment_id => $environment_name) { // get any payment tokens $payment_tokens = $gateway->get_payment_tokens($user->ID, null, $environment_id); ?> <table class="form-table"> <tr> <th style="padding-bottom:0px;"><?php echo count($environments) > 1 ? sprintf(__('%s Payment Tokens', $this->text_domain), $environment_name) : __('Payment Tokens', $this->text_domain); ?> </th> <td style="padding-bottom:0px;"> <?php if (empty($payment_tokens)) { echo "<p>" . __('This customer has no saved payment tokens', $this->text_domain) . "</p>"; } else { ?> <ul style="margin:0;"> <?php foreach ($payment_tokens as $token) { ?> <li> <?php echo $token->get_token(); ?> (<?php printf('%s ending in %s expiring %s', $token->get_type_full(), $token->get_last_four(), $token->get_exp_month() . '/' . $token->get_exp_year()); echo $token->is_default() ? ' <strong>' . __('Default card', $this->text_domain) . '</strong>' : ''; ?> ) <a href="#" class="js-sv-wc-payment-token-delete" data-payment_token="<?php echo $token->get_token(); ?> "><?php _e('Delete', $this->text_domain); ?> </a> </li> <?php } ?> </ul> <input type="hidden" class="js-sv-wc-payment-tokens-deleted" name="wc_<?php echo $gateway->get_id(); ?> _payment_tokens_deleted_<?php echo $environment_id; ?> " value="" /> <?php } ?> </td> </tr> <tr> <th style="padding-top:0px;"><?php _e('Add a Payment Token', $this->text_domain); ?> </th> <td style="padding-top:0px;"> <input type="text" name="wc_<?php echo $gateway->get_id(); ?> _payment_token_<?php echo $environment_id; ?> " placeholder="<?php esc_attr_e('Token', $this->text_domain); ?> " style="width:145px;" /> <?php if ($gateway->supports(SV_WC_Payment_Gateway::FEATURE_CARD_TYPES)) { ?> <select name="wc_<?php echo $gateway->get_id(); ?> _payment_token_type_<?php echo $environment_id; ?> "> <option value=""><?php _e("Card Type", $this->text_domain); ?> </option> <?php foreach ($gateway->get_card_types() as $card_type) { $card_type = strtolower($card_type); ?> <option value="<?php echo $card_type; ?> "><?php echo SV_WC_Payment_Gateway_Payment_Token::type_to_name($card_type); ?> </option> <?php } ?> </select> <?php } ?> <input type="text" name="wc_<?php echo $gateway->get_id(); ?> _payment_token_last_four_<?php echo $environment_id; ?> " placeholder="<?php printf(esc_attr__('Last Four', $this->text_domain), substr(date('Y') + 1, -2)); ?> " style="width:75px;" /> <input type="text" name="wc_<?php echo $gateway->get_id(); ?> _payment_token_exp_date_<?php echo $environment_id; ?> " placeholder="<?php printf(esc_attr__('Expiry Date (01/%s)', $this->text_domain), date('Y') + 1); ?> " style="width:155px;" /> <br/> <span class="description"><?php echo apply_filters('wc_payment_gateway_' . $gateway->get_id() . '_user_profile_add_token_description', '', $gateway, $user); ?> </span> </td> </tr> </table> <?php } $this->maybe_add_user_profile_tokenization_fields_js(); } }
/** * Adds an order note, along with anything else required after an approved * credit card transaction * * @since 2.2.0 * @param WC_Order $order the order * @param SV_WC_Payment_Gateway_API_Payment_Notification_Credit_Card_Response transaction response */ protected function do_credit_card_transaction_approved($order, $response) { $last_four = substr($response->get_account_number(), -4); $transaction_type = ''; if ($response->is_authorization()) { $transaction_type = 'Authorization'; } elseif ($response->is_charge()) { $transaction_type = 'Charge'; } // credit card order note $message = sprintf(__('%s %s %s Approved: %s ending in %s (expires %s)', $this->text_domain), $this->get_method_title(), $this->is_test_environment() ? 'Test' : '', $transaction_type, $response->get_card_type() ? SV_WC_Payment_Gateway_Payment_Token::type_to_name($response->get_card_type()) : 'card', $last_four, $response->get_exp_month() . '/' . substr($response->get_exp_year(), -2)); // adds the transaction id (if any) to the order note if ($response->get_transaction_id()) { $message .= ' ' . sprintf(__('(Transaction ID %s)', $this->text_domain), $response->get_transaction_id()); } $order->add_order_note($message); }
/** * Process a pre-order payment when the pre-order is released * * @since 1.0.0 * @param WC_Order $order original order containing the pre-order */ public function process_pre_order_release_payment($order) { try { // set order defaults $order = $this->get_order($order->id); // order description $order->description = sprintf(_x('%s - Pre-Order Release Payment for Order %s', 'Supports direct payment method pre-orders', $this->text_domain), esc_html(get_bloginfo('name')), $order->get_order_number()); // token is required if (!$order->payment->token) { throw new SV_WC_Payment_Gateway_Exception(_x('Payment token missing/invalid.', 'Supports direct payment method pre-orders', $this->text_domain)); } // perform the transaction if ($this->is_credit_card_gateway()) { if ($this->perform_credit_card_charge()) { $response = $this->get_api()->credit_card_charge($order); } else { $response = $this->get_api()->credit_card_authorization($order); } } elseif ($this->is_echeck_gateway()) { $response = $this->get_api()->check_debit($order); } // success! update order record if ($response->transaction_approved()) { $last_four = substr($order->payment->account_number, -4); // order note based on gateway type if ($this->is_credit_card_gateway()) { $message = sprintf(_x('%s %s Pre-Order Release Payment Approved: %s ending in %s (expires %s)', 'Supports direct payment method pre-orders', $this->text_domain), $this->get_method_title(), $this->perform_credit_card_authorization() ? 'Authorization' : 'Charge', isset($order->payment->card_type) && $order->payment->card_type ? SV_WC_Payment_Gateway_Payment_Token::type_to_name($order->payment->card_type) : 'card', $last_four, $order->payment->exp_month . '/' . substr($order->payment->exp_year, -2)); } elseif ($this->is_echeck_gateway()) { // account type (checking/savings) may or may not be available, which is fine $message = sprintf(_x('%s eCheck Pre-Order Release Payment Approved: %s account ending in %s', 'Supports direct payment method pre-orders', $this->text_domain), $this->get_method_title(), $order->payment->account_type, $last_four); } // adds the transaction id (if any) to the order note if ($response->get_transaction_id()) { $message .= ' ' . sprintf(_x('(Transaction ID %s)', 'Supports direct payment method pre-orders', $this->text_domain), $response->get_transaction_id()); } $order->add_order_note($message); } if ($response->transaction_approved() || $response->transaction_held()) { // add the standard transaction data $this->add_transaction_data($order, $response); // allow the concrete class to add any gateway-specific transaction data to the order $this->add_payment_gateway_transaction_data($order, $response); // if the transaction was held (ie fraud validation failure) mark it as such if ($response->transaction_held() || $this->supports(self::FEATURE_CREDIT_CARD_AUTHORIZATION) && $this->perform_credit_card_authorization()) { $this->mark_order_as_held($order, $this->supports(self::FEATURE_CREDIT_CARD_AUTHORIZATION) && $this->perform_credit_card_authorization() ? _x('Authorization only transaction', 'Supports direct payment method pre-orders', $this->text_domain) : $response->get_status_message(), $response); $order->reduce_order_stock(); // reduce stock for held orders, but don't complete payment } else { // otherwise complete the order $order->payment_complete(); } } else { // failure throw new SV_WC_Payment_Gateway_Exception(sprintf('%s: %s', $response->get_status_code(), $response->get_status_message())); } } catch (SV_WC_Plugin_Exception $e) { // Mark order as failed $this->mark_order_as_failed($order, sprintf(_x('Pre-Order Release Payment Failed: %s', 'Supports direct payment method pre-orders', $this->text_domain), $e->getMessage())); } }