woocommerce /
woocommerce-gateway-stripe
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | if ( ! defined( 'ABSPATH' ) ) { |
||
| 3 | exit; |
||
| 4 | } |
||
| 5 | |||
| 6 | /** |
||
| 7 | * WC_Gateway_Stripe class. |
||
| 8 | * |
||
| 9 | * @extends WC_Payment_Gateway |
||
| 10 | */ |
||
| 11 | class WC_Gateway_Stripe extends WC_Stripe_Payment_Gateway { |
||
| 12 | /** |
||
| 13 | * Should we capture Credit cards |
||
| 14 | * |
||
| 15 | * @var bool |
||
| 16 | */ |
||
| 17 | public $capture; |
||
| 18 | |||
| 19 | /** |
||
| 20 | * Alternate credit card statement name |
||
| 21 | * |
||
| 22 | * @var bool |
||
| 23 | */ |
||
| 24 | public $statement_descriptor; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * Checkout enabled |
||
| 28 | * |
||
| 29 | * @var bool |
||
| 30 | */ |
||
| 31 | public $stripe_checkout; |
||
| 32 | |||
| 33 | /** |
||
| 34 | * Require 3D Secure enabled |
||
| 35 | * |
||
| 36 | * @var bool |
||
| 37 | */ |
||
| 38 | public $three_d_secure; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * Checkout Locale |
||
| 42 | * |
||
| 43 | * @var string |
||
| 44 | */ |
||
| 45 | public $stripe_checkout_locale; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Credit card image |
||
| 49 | * |
||
| 50 | * @var string |
||
| 51 | */ |
||
| 52 | public $stripe_checkout_image; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * Should we store the users credit cards? |
||
| 56 | * |
||
| 57 | * @var bool |
||
| 58 | */ |
||
| 59 | public $saved_cards; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * API access secret key |
||
| 63 | * |
||
| 64 | * @var string |
||
| 65 | */ |
||
| 66 | public $secret_key; |
||
| 67 | |||
| 68 | /** |
||
| 69 | * Api access publishable key |
||
| 70 | * |
||
| 71 | * @var string |
||
| 72 | */ |
||
| 73 | public $publishable_key; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * Do we accept bitcoin? |
||
| 77 | * |
||
| 78 | * @var bool |
||
| 79 | */ |
||
| 80 | public $bitcoin; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * Do we accept Payment Request? |
||
| 84 | * |
||
| 85 | * @var bool |
||
| 86 | */ |
||
| 87 | public $payment_request; |
||
| 88 | |||
| 89 | /** |
||
| 90 | * Apple Pay Domain Set. |
||
| 91 | * |
||
| 92 | * @var bool |
||
| 93 | */ |
||
| 94 | public $apple_pay_domain_set; |
||
| 95 | |||
| 96 | /** |
||
| 97 | * Is test mode active? |
||
| 98 | * |
||
| 99 | * @var bool |
||
| 100 | */ |
||
| 101 | public $testmode; |
||
| 102 | |||
| 103 | /** |
||
| 104 | * Stores Apple Pay domain verification issues. |
||
| 105 | * |
||
| 106 | * @var string |
||
| 107 | */ |
||
| 108 | public $apple_pay_verify_notice; |
||
| 109 | |||
| 110 | /** |
||
| 111 | * Inline CC form styling |
||
| 112 | * |
||
| 113 | * @var string |
||
| 114 | */ |
||
| 115 | public $inline_cc_form; |
||
| 116 | |||
| 117 | /** |
||
| 118 | * Constructor |
||
| 119 | */ |
||
| 120 | public function __construct() { |
||
| 121 | $this->id = 'stripe'; |
||
| 122 | $this->method_title = __( 'Stripe', 'woocommerce-gateway-stripe' ); |
||
| 123 | /* translators: 1) link to Stripe register page 2) link to Stripe api keys page */ |
||
| 124 | $this->method_description = sprintf( __( 'Stripe works by adding payment fields on the checkout and then sending the details to Stripe for verification. <a href="%1$s" target="_blank">Sign up</a> for a Stripe account, and <a href="%2$s" target="_blank">get your Stripe account keys</a>.', 'woocommerce-gateway-stripe' ), 'https://dashboard.stripe.com/register', 'https://dashboard.stripe.com/account/apikeys' ); |
||
| 125 | $this->has_fields = true; |
||
| 126 | $this->supports = array( |
||
| 127 | 'products', |
||
| 128 | 'refunds', |
||
| 129 | 'tokenization', |
||
| 130 | 'add_payment_method', |
||
| 131 | 'subscriptions', |
||
| 132 | 'subscription_cancellation', |
||
| 133 | 'subscription_suspension', |
||
| 134 | 'subscription_reactivation', |
||
| 135 | 'subscription_amount_changes', |
||
| 136 | 'subscription_date_changes', |
||
| 137 | 'subscription_payment_method_change', |
||
| 138 | 'subscription_payment_method_change_customer', |
||
| 139 | 'subscription_payment_method_change_admin', |
||
| 140 | 'multiple_subscriptions', |
||
| 141 | 'pre-orders', |
||
| 142 | ); |
||
| 143 | |||
| 144 | // Load the form fields. |
||
| 145 | $this->init_form_fields(); |
||
| 146 | |||
| 147 | // Load the settings. |
||
| 148 | $this->init_settings(); |
||
| 149 | |||
| 150 | // Get setting values. |
||
| 151 | $this->title = $this->get_option( 'title' ); |
||
| 152 | $this->description = $this->get_option( 'description' ); |
||
| 153 | $this->enabled = $this->get_option( 'enabled' ); |
||
| 154 | $this->testmode = 'yes' === $this->get_option( 'testmode' ); |
||
| 155 | $this->inline_cc_form = 'yes' === $this->get_option( 'inline_cc_form' ); |
||
|
0 ignored issues
–
show
|
|||
| 156 | $this->capture = 'yes' === $this->get_option( 'capture', 'yes' ); |
||
| 157 | $this->statement_descriptor = WC_Stripe_Helper::clean_statement_descriptor( $this->get_option( 'statement_descriptor' ) ); |
||
|
0 ignored issues
–
show
The property
$statement_descriptor was declared of type boolean, but \WC_Stripe_Helper::clean...statement_descriptor')) is of type string. Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
Loading history...
|
|||
| 158 | $this->three_d_secure = 'yes' === $this->get_option( 'three_d_secure' ); |
||
| 159 | $this->stripe_checkout = 'yes' === $this->get_option( 'stripe_checkout' ); |
||
| 160 | $this->stripe_checkout_locale = $this->get_option( 'stripe_checkout_locale' ); |
||
| 161 | $this->stripe_checkout_image = $this->get_option( 'stripe_checkout_image', '' ); |
||
| 162 | $this->saved_cards = 'yes' === $this->get_option( 'saved_cards' ); |
||
| 163 | $this->secret_key = $this->testmode ? $this->get_option( 'test_secret_key' ) : $this->get_option( 'secret_key' ); |
||
| 164 | $this->publishable_key = $this->testmode ? $this->get_option( 'test_publishable_key' ) : $this->get_option( 'publishable_key' ); |
||
| 165 | $this->bitcoin = 'USD' === strtoupper( get_woocommerce_currency() ) && 'yes' === $this->get_option( 'stripe_bitcoin' ); |
||
| 166 | $this->payment_request = 'yes' === $this->get_option( 'payment_request', 'yes' ); |
||
| 167 | $this->apple_pay_domain_set = 'yes' === $this->get_option( 'apple_pay_domain_set', 'no' ); |
||
| 168 | $this->apple_pay_verify_notice = ''; |
||
| 169 | |||
| 170 | if ( $this->stripe_checkout ) { |
||
| 171 | $this->order_button_text = __( 'Continue to payment', 'woocommerce-gateway-stripe' ); |
||
| 172 | } |
||
| 173 | |||
| 174 | WC_Stripe_API::set_secret_key( $this->secret_key ); |
||
| 175 | |||
| 176 | $this->init_apple_pay(); |
||
| 177 | |||
| 178 | // Hooks. |
||
| 179 | add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) ); |
||
| 180 | add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) ); |
||
| 181 | add_action( 'admin_notices', array( $this, 'admin_notices' ) ); |
||
| 182 | add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); |
||
| 183 | } |
||
| 184 | |||
| 185 | /** |
||
| 186 | * All payment icons that work with Stripe. |
||
| 187 | * |
||
| 188 | * @since 4.0.0 |
||
| 189 | * @version 4.0.0 |
||
| 190 | * @return array |
||
| 191 | */ |
||
| 192 | public function payment_icons() { |
||
| 193 | return apply_filters( 'wc_stripe_payment_icons', array( |
||
| 194 | 'visa' => '<i class="stripe-pf stripe-pf-visa stripe-pf-right" alt="Visa" aria-hidden="true"></i>', |
||
| 195 | 'amex' => '<i class="stripe-pf stripe-pf-american-express stripe-pf-right" alt="Amex" aria-hidden="true"></i>', |
||
| 196 | 'mastercard' => '<i class="stripe-pf stripe-pf-mastercard stripe-pf-right" alt="Mastercard" aria-hidden="true"></i>', |
||
| 197 | 'discover' => '<i class="stripe-pf stripe-pf-discover stripe-pf-right" alt="Discover" aria-hidden="true"></i>', |
||
| 198 | 'diners' => '<i class="stripe-pf stripe-pf-diners stripe-pf-right" alt="Diners" aria-hidden="true"></i>', |
||
| 199 | 'jcb' => '<i class="stripe-pf stripe-pf-jcb stripe-pf-right" alt="JCB" aria-hidden="true"></i>', |
||
| 200 | 'alipay' => '<i class="stripe-pf stripe-pf-alipay stripe-pf-right" alt="Alipay" aria-hidden="true"></i>', |
||
| 201 | 'wechat' => '<i class="stripe-pf stripe-pf-wechat-pay stripe-pf-right" alt="Wechat Pay" aria-hidden="true"></i>', |
||
| 202 | 'bitcoin' => '<i class="stripe-pf stripe-pf-bitcoin stripe-pf-right" alt="Bitcoin" aria-hidden="true"></i>', |
||
| 203 | 'bancontact' => '<i class="stripe-pf stripe-pf-bancontact-mister-cash stripe-pf-right" alt="Bancontact" aria-hidden="true"></i>', |
||
| 204 | 'ideal' => '<i class="stripe-pf stripe-pf-ideal stripe-pf-right" alt="iDeal" aria-hidden="true"></i>', |
||
| 205 | 'p24' => '<i class="stripe-pf stripe-pf-p24 stripe-pf-right" alt="P24" aria-hidden="true"></i>', |
||
| 206 | 'giropay' => '<i class="stripe-pf stripe-pf-giropay stripe-pf-right" alt="Giropay" aria-hidden="true"></i>', |
||
| 207 | 'eps' => '<i class="stripe-pf stripe-pf-eps stripe-pf-right" alt="EPS" aria-hidden="true"></i>', |
||
| 208 | 'sofort' => '<i class="stripe-pf stripe-pf-sofort stripe-pf-right" alt="SOFORT" aria-hidden="true"></i>', |
||
| 209 | 'sepa' => '<i class="stripe-pf stripe-pf-sepa stripe-pf-right" alt="SEPA" aria-hidden="true"></i>', |
||
| 210 | ) ); |
||
| 211 | } |
||
| 212 | |||
| 213 | /** |
||
| 214 | * Get_icon function. |
||
| 215 | * |
||
| 216 | * @since 1.0.0 |
||
| 217 | * @version 4.0.0 |
||
| 218 | * @return string |
||
| 219 | */ |
||
| 220 | public function get_icon() { |
||
| 221 | $icons = $this->payment_icons(); |
||
| 222 | |||
| 223 | $icons_str = ''; |
||
| 224 | |||
| 225 | $icons_str .= $icons['visa']; |
||
| 226 | $icons_str .= $icons['amex']; |
||
| 227 | $icons_str .= $icons['mastercard']; |
||
| 228 | |||
| 229 | if ( 'USD' === get_woocommerce_currency() ) { |
||
| 230 | $icons_str .= $icons['discover']; |
||
| 231 | $icons_str .= $icons['jcb']; |
||
| 232 | $icons_str .= $icons['diners']; |
||
| 233 | } |
||
| 234 | |||
| 235 | if ( $this->bitcoin && $this->stripe_checkout ) { |
||
| 236 | $icons_str .= $icons['bitcoin']; |
||
| 237 | } |
||
| 238 | |||
| 239 | return apply_filters( 'woocommerce_gateway_icon', $icons_str, $this->id ); |
||
| 240 | } |
||
| 241 | |||
| 242 | /** |
||
| 243 | * Initializes Apple Pay process on settings page. |
||
| 244 | * |
||
| 245 | * @since 3.1.0 |
||
| 246 | * @version 3.1.0 |
||
| 247 | */ |
||
| 248 | public function init_apple_pay() { |
||
| 249 | if ( |
||
| 250 | is_admin() && |
||
| 251 | isset( $_GET['page'] ) && 'wc-settings' === $_GET['page'] && |
||
| 252 | isset( $_GET['tab'] ) && 'checkout' === $_GET['tab'] && |
||
| 253 | isset( $_GET['section'] ) && 'stripe' === $_GET['section'] && |
||
| 254 | $this->payment_request |
||
| 255 | ) { |
||
| 256 | $this->process_apple_pay_verification(); |
||
| 257 | } |
||
| 258 | } |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Registers the domain with Stripe/Apple Pay |
||
| 262 | * |
||
| 263 | * @since 3.1.0 |
||
| 264 | * @version 3.1.0 |
||
| 265 | * @param string $secret_key |
||
| 266 | */ |
||
| 267 | private function register_apple_pay_domain( $secret_key = '' ) { |
||
| 268 | if ( empty( $secret_key ) ) { |
||
| 269 | throw new Exception( __( 'Unable to verify domain - missing secret key.', 'woocommerce-gateway-stripe' ) ); |
||
| 270 | } |
||
| 271 | |||
| 272 | $endpoint = 'https://api.stripe.com/v1/apple_pay/domains'; |
||
| 273 | |||
| 274 | $data = array( |
||
| 275 | 'domain_name' => $_SERVER['HTTP_HOST'], |
||
| 276 | ); |
||
| 277 | |||
| 278 | $headers = array( |
||
| 279 | 'User-Agent' => 'WooCommerce Stripe Apple Pay', |
||
| 280 | 'Authorization' => 'Bearer ' . $secret_key, |
||
| 281 | ); |
||
| 282 | |||
| 283 | $response = wp_remote_post( $endpoint, array( |
||
| 284 | 'headers' => $headers, |
||
| 285 | 'body' => http_build_query( $data ), |
||
| 286 | ) ); |
||
| 287 | |||
| 288 | if ( is_wp_error( $response ) ) { |
||
| 289 | /* translators: error message */ |
||
| 290 | throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $response->get_error_message() ) ); |
||
| 291 | } |
||
| 292 | |||
| 293 | if ( 200 !== $response['response']['code'] ) { |
||
| 294 | $parsed_response = json_decode( $response['body'] ); |
||
| 295 | |||
| 296 | $this->apple_pay_verify_notice = $parsed_response->error->message; |
||
| 297 | |||
| 298 | /* translators: error message */ |
||
| 299 | throw new Exception( sprintf( __( 'Unable to verify domain - %s', 'woocommerce-gateway-stripe' ), $parsed_response->error->message ) ); |
||
| 300 | } |
||
| 301 | } |
||
| 302 | |||
| 303 | /** |
||
| 304 | * Processes the Apple Pay domain verification. |
||
| 305 | * |
||
| 306 | * @since 3.1.0 |
||
| 307 | * @version 3.1.0 |
||
| 308 | */ |
||
| 309 | public function process_apple_pay_verification() { |
||
| 310 | $gateway_settings = get_option( 'woocommerce_stripe_settings', array() ); |
||
| 311 | |||
| 312 | try { |
||
| 313 | $path = untrailingslashit( $_SERVER['DOCUMENT_ROOT'] ); |
||
| 314 | $dir = '.well-known'; |
||
| 315 | $file = 'apple-developer-merchantid-domain-association'; |
||
| 316 | $fullpath = $path . '/' . $dir . '/' . $file; |
||
| 317 | |||
| 318 | if ( ! empty( $gateway_settings['apple_pay_domain_set'] ) && 'yes' === $gateway_settings['apple_pay_domain_set'] && file_exists( $fullpath ) ) { |
||
| 319 | return; |
||
| 320 | } |
||
| 321 | |||
| 322 | if ( ! file_exists( $path . '/' . $dir ) ) { |
||
| 323 | if ( ! @mkdir( $path . '/' . $dir, 0755 ) ) { |
||
| 324 | throw new Exception( __( 'Unable to create domain association folder to domain root.', 'woocommerce-gateway-stripe' ) ); |
||
| 325 | } |
||
| 326 | } |
||
| 327 | |||
| 328 | if ( ! file_exists( $fullpath ) ) { |
||
| 329 | if ( ! @copy( WC_STRIPE_PLUGIN_PATH . '/' . $file, $fullpath ) ) { |
||
| 330 | throw new Exception( __( 'Unable to copy domain association file to domain root.', 'woocommerce-gateway-stripe' ) ); |
||
| 331 | } |
||
| 332 | } |
||
| 333 | |||
| 334 | // At this point then the domain association folder and file should be available. |
||
| 335 | // Proceed to verify/and or verify again. |
||
| 336 | $this->register_apple_pay_domain( $this->secret_key ); |
||
| 337 | |||
| 338 | // No errors to this point, verification success! |
||
| 339 | $gateway_settings['apple_pay_domain_set'] = 'yes'; |
||
| 340 | $this->apple_pay_domain_set = true; |
||
| 341 | |||
| 342 | update_option( 'woocommerce_stripe_settings', $gateway_settings ); |
||
| 343 | |||
| 344 | WC_Stripe_Logger::log( 'Your domain has been verified with Apple Pay!' ); |
||
| 345 | |||
| 346 | } catch ( Exception $e ) { |
||
| 347 | $gateway_settings['apple_pay_domain_set'] = 'no'; |
||
| 348 | |||
| 349 | update_option( 'woocommerce_stripe_settings', $gateway_settings ); |
||
| 350 | |||
| 351 | WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() ); |
||
| 352 | } |
||
| 353 | } |
||
| 354 | |||
| 355 | /** |
||
| 356 | * Check if SSL is enabled and notify the user |
||
| 357 | */ |
||
| 358 | public function admin_notices() { |
||
| 359 | if ( 'no' === $this->enabled ) { |
||
| 360 | return; |
||
| 361 | } |
||
| 362 | |||
| 363 | if ( $this->payment_request && ! empty( $this->apple_pay_verify_notice ) ) { |
||
| 364 | $allowed_html = array( |
||
| 365 | 'a' => array( |
||
| 366 | 'href' => array(), |
||
| 367 | 'title' => array(), |
||
| 368 | ), |
||
| 369 | ); |
||
| 370 | |||
| 371 | echo '<div class="error stripe-apple-pay-message"><p>' . wp_kses( make_clickable( $this->apple_pay_verify_notice ), $allowed_html ) . '</p></div>'; |
||
| 372 | } |
||
| 373 | |||
| 374 | /** |
||
| 375 | * Apple pay is enabled by default and domain verification initializes |
||
| 376 | * when setting screen is displayed. So if domain verification is not set, |
||
| 377 | * something went wrong so lets notify user. |
||
| 378 | */ |
||
| 379 | if ( ! empty( $this->secret_key ) && $this->payment_request && ! $this->apple_pay_domain_set ) { |
||
| 380 | /* translators: 1) HTML anchor open tag 2) HTML anchor closing tag */ |
||
| 381 | echo '<div class="error stripe-apple-pay-message"><p>' . sprintf( __( 'Apple Pay domain verification failed. Please check the %1$slog%2$s to see the issue. (Logging must be enabled to see recorded logs)', 'woocommerce-gateway-stripe' ), '<a href="' . admin_url( 'admin.php?page=wc-status&tab=logs' ) . '">', '</a>' ) . '</p></div>'; |
||
| 382 | } |
||
| 383 | } |
||
| 384 | |||
| 385 | /** |
||
| 386 | * Initialise Gateway Settings Form Fields |
||
| 387 | */ |
||
| 388 | public function init_form_fields() { |
||
| 389 | $this->form_fields = require( dirname( __FILE__ ) . '/admin/stripe-settings.php' ); |
||
| 390 | } |
||
| 391 | |||
| 392 | /** |
||
| 393 | * Payment form on checkout page |
||
| 394 | */ |
||
| 395 | public function payment_fields() { |
||
| 396 | $user = wp_get_current_user(); |
||
| 397 | $display_tokenization = $this->supports( 'tokenization' ) && is_checkout() && $this->saved_cards; |
||
| 398 | $total = WC()->cart->total; |
||
| 399 | $user_email = ''; |
||
| 400 | |||
| 401 | // If paying from order, we need to get total from order not cart. |
||
| 402 | if ( isset( $_GET['pay_for_order'] ) && ! empty( $_GET['key'] ) ) { |
||
| 403 | $order = wc_get_order( wc_get_order_id_by_order_key( wc_clean( $_GET['key'] ) ) ); |
||
| 404 | $total = $order->get_total(); |
||
| 405 | $user_email = WC_Stripe_Helper::is_pre_30() ? $order->billing_email : $order->get_billing_email(); |
||
| 406 | } else { |
||
| 407 | if ( $user->ID ) { |
||
| 408 | $user_email = get_user_meta( $user->ID, 'billing_email', true ); |
||
| 409 | $user_email = $user_email ? $user_email : $user->user_email; |
||
| 410 | } |
||
| 411 | } |
||
| 412 | |||
| 413 | if ( is_add_payment_method_page() ) { |
||
| 414 | $pay_button_text = __( 'Add Card', 'woocommerce-gateway-stripe' ); |
||
| 415 | $total = ''; |
||
| 416 | } else { |
||
| 417 | $pay_button_text = ''; |
||
| 418 | } |
||
| 419 | |||
| 420 | echo '<div |
||
| 421 | id="stripe-payment-data" |
||
| 422 | data-panel-label="' . esc_attr( $pay_button_text ) . '" |
||
| 423 | data-description="" |
||
| 424 | data-email="' . esc_attr( $user_email ) . '" |
||
| 425 | data-amount="' . esc_attr( WC_Stripe_Helper::get_stripe_amount( $total ) ) . '" |
||
| 426 | data-name="' . esc_attr( $this->statement_descriptor ) . '" |
||
| 427 | data-currency="' . esc_attr( strtolower( get_woocommerce_currency() ) ) . '" |
||
| 428 | data-image="' . esc_attr( $this->stripe_checkout_image ) . '" |
||
| 429 | data-bitcoin="' . esc_attr( $this->bitcoin ? 'true' : 'false' ) . '" |
||
| 430 | data-locale="' . esc_attr( $this->stripe_checkout_locale ? $this->stripe_checkout_locale : 'en' ) . '" |
||
| 431 | data-three-d-secure="' . esc_attr( $this->three_d_secure ? 'true' : 'false' ) . '" |
||
| 432 | data-allow-remember-me="' . esc_attr( $this->saved_cards ? 'true' : 'false' ) . '">'; |
||
| 433 | |||
| 434 | View Code Duplication | if ( $this->description ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 435 | if ( $this->testmode ) { |
||
| 436 | /* translators: link to Stripe testing page */ |
||
| 437 | $this->description .= ' ' . sprintf( __( 'TEST MODE ENABLED. In test mode, you can use the card number 4242424242424242 with any CVC and a valid expiration date or check the documentation "<a href="%s" target="_blank">Testing Stripe</a>" for more card numbers.', 'woocommerce-gateway-stripe' ), 'https://stripe.com/docs/testing' ); |
||
| 438 | $this->description = trim( $this->description ); |
||
| 439 | } |
||
| 440 | echo apply_filters( 'wc_stripe_description', wpautop( wp_kses_post( $this->description ) ) ); |
||
| 441 | } |
||
| 442 | |||
| 443 | if ( $display_tokenization ) { |
||
| 444 | $this->tokenization_script(); |
||
| 445 | $this->saved_payment_methods(); |
||
| 446 | } |
||
| 447 | |||
| 448 | if ( ! $this->stripe_checkout ) { |
||
| 449 | if ( apply_filters( 'wc_stripe_use_elements_checkout_form', true ) ) { |
||
| 450 | $this->elements_form(); |
||
| 451 | } else { |
||
| 452 | $this->form(); |
||
| 453 | echo '<div class="stripe-source-errors" role="alert"></div>'; |
||
| 454 | } |
||
| 455 | } |
||
| 456 | |||
| 457 | View Code Duplication | if ( apply_filters( 'wc_stripe_display_save_payment_method_checkbox', $display_tokenization ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) { |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 458 | $this->save_payment_method_checkbox(); |
||
| 459 | } |
||
| 460 | |||
| 461 | echo '</div>'; |
||
| 462 | } |
||
| 463 | |||
| 464 | /** |
||
| 465 | * Renders the Stripe elements form. |
||
| 466 | * |
||
| 467 | * @since 4.0.0 |
||
| 468 | * @version 4.0.0 |
||
| 469 | */ |
||
| 470 | public function elements_form() { |
||
| 471 | ?> |
||
| 472 | <fieldset id="wc-<?php echo esc_attr( $this->id ); ?>-cc-form" class="wc-credit-card-form wc-payment-form" style="background:transparent;"> |
||
| 473 | <?php do_action( 'woocommerce_credit_card_form_start', $this->id ); ?> |
||
| 474 | <label for="card-element"> |
||
| 475 | <?php esc_html_e( 'Credit or debit card', 'woocommerce-gateway-stripe' ); ?> |
||
| 476 | </label> |
||
| 477 | |||
| 478 | <?php if ( $this->inline_cc_form ) { ?> |
||
| 479 | <div id="stripe-card-element" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;"> |
||
| 480 | <!-- a Stripe Element will be inserted here. --> |
||
| 481 | </div> |
||
| 482 | <?php } else { ?> |
||
| 483 | <div id="stripe-card-element" class="form-row form-row-wide" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;"> |
||
| 484 | <!-- a Stripe Element will be inserted here. --> |
||
| 485 | </div> |
||
| 486 | <div id="stripe-exp-element" class="form-row form-row-first" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;"> |
||
| 487 | <!-- a Stripe Element will be inserted here. --> |
||
| 488 | </div> |
||
| 489 | <div id="stripe-cvc-element" class="form-row form-row-last" style="background:#f2f2f2;padding:0 1em;box-shadow:inset 0 1px 1px rgba(0,0,0,.125);margin:5px 0;padding:10px 5px;"> |
||
| 490 | <!-- a Stripe Element will be inserted here. --> |
||
| 491 | </div> |
||
| 492 | <div class="clear"></div> |
||
| 493 | <?php } ?> |
||
| 494 | |||
| 495 | <!-- Used to display form errors --> |
||
| 496 | <div class="stripe-source-errors" role="alert"></div> |
||
| 497 | <?php do_action( 'woocommerce_credit_card_form_end', $this->id ); ?> |
||
| 498 | <div class="clear"></div> |
||
| 499 | </fieldset> |
||
| 500 | <?php |
||
| 501 | } |
||
| 502 | |||
| 503 | /** |
||
| 504 | * Load admin scripts. |
||
| 505 | * |
||
| 506 | * @since 3.1.0 |
||
| 507 | * @version 3.1.0 |
||
| 508 | */ |
||
| 509 | public function admin_scripts() { |
||
| 510 | if ( 'woocommerce_page_wc-settings' !== get_current_screen()->id ) { |
||
| 511 | return; |
||
| 512 | } |
||
| 513 | |||
| 514 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
||
| 515 | |||
| 516 | wp_enqueue_script( 'woocommerce_stripe_admin', plugins_url( 'assets/js/stripe-admin' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array(), WC_STRIPE_VERSION, true ); |
||
| 517 | } |
||
| 518 | |||
| 519 | /** |
||
| 520 | * Payment_scripts function. |
||
| 521 | * |
||
| 522 | * Outputs scripts used for stripe payment |
||
| 523 | * |
||
| 524 | * @since 3.1.0 |
||
| 525 | * @version 4.0.0 |
||
| 526 | */ |
||
| 527 | public function payment_scripts() { |
||
| 528 | if ( ! is_cart() && ! is_checkout() && ! isset( $_GET['pay_for_order'] ) && ! is_add_payment_method_page() && ! isset( $_GET['change_payment_method'] ) ) { |
||
| 529 | return; |
||
| 530 | } |
||
| 531 | |||
| 532 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
||
| 533 | |||
| 534 | wp_register_style( 'stripe_paymentfonts', plugins_url( 'assets/css/stripe-paymentfonts.css', WC_STRIPE_MAIN_FILE ), array(), '1.2.5' ); |
||
| 535 | wp_enqueue_style( 'stripe_paymentfonts' ); |
||
| 536 | wp_register_script( 'stripe_checkout', 'https://checkout.stripe.com/checkout.js', '', WC_STRIPE_VERSION, true ); |
||
| 537 | wp_register_script( 'stripev2', 'https://js.stripe.com/v2/', '', '2.0', true ); |
||
| 538 | wp_register_script( 'stripe', 'https://js.stripe.com/v3/', '', '3.0', true ); |
||
| 539 | wp_register_script( 'woocommerce_stripe', plugins_url( 'assets/js/stripe' . $suffix . '.js', WC_STRIPE_MAIN_FILE ), array( 'jquery-payment', 'stripev2', 'stripe' ), WC_STRIPE_VERSION, true ); |
||
| 540 | |||
| 541 | $stripe_params = array( |
||
| 542 | 'key' => $this->publishable_key, |
||
| 543 | 'i18n_terms' => __( 'Please accept the terms and conditions first', 'woocommerce-gateway-stripe' ), |
||
| 544 | 'i18n_required_fields' => __( 'Please fill in required checkout fields first', 'woocommerce-gateway-stripe' ), |
||
| 545 | ); |
||
| 546 | |||
| 547 | // If we're on the pay page we need to pass stripe.js the address of the order. |
||
| 548 | if ( isset( $_GET['pay_for_order'] ) && 'true' === $_GET['pay_for_order'] ) { |
||
| 549 | $order_id = wc_get_order_id_by_order_key( urldecode( $_GET['key'] ) ); |
||
| 550 | $order = wc_get_order( $order_id ); |
||
| 551 | |||
| 552 | $stripe_params['billing_first_name'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_first_name : $order->get_billing_first_name(); |
||
| 553 | $stripe_params['billing_last_name'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_last_name : $order->get_billing_last_name(); |
||
| 554 | $stripe_params['billing_address_1'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_address_1 : $order->get_billing_address_1(); |
||
| 555 | $stripe_params['billing_address_2'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_address_2 : $order->get_billing_address_2(); |
||
| 556 | $stripe_params['billing_state'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_state : $order->get_billing_state(); |
||
| 557 | $stripe_params['billing_city'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_city : $order->get_billing_city(); |
||
| 558 | $stripe_params['billing_postcode'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_postcode : $order->get_billing_postcode(); |
||
| 559 | $stripe_params['billing_country'] = WC_Stripe_Helper::is_pre_30() ? $order->billing_country : $order->get_billing_country(); |
||
| 560 | } |
||
| 561 | |||
| 562 | $stripe_params['no_prepaid_card_msg'] = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charge. Please try with alternative payment method.', 'woocommerce-gateway-stripe' ); |
||
| 563 | $stripe_params['no_bank_country_msg'] = __( 'Please select a country for your bank.', 'woocommerce-gateway-stripe' ); |
||
| 564 | $stripe_params['no_sepa_owner_msg'] = __( 'Please enter your IBAN account name.', 'woocommerce-gateway-stripe' ); |
||
| 565 | $stripe_params['no_sepa_iban_msg'] = __( 'Please enter your IBAN account number.', 'woocommerce-gateway-stripe' ); |
||
| 566 | $stripe_params['allow_prepaid_card'] = apply_filters( 'wc_stripe_allow_prepaid_card', true ) ? 'yes' : 'no'; |
||
| 567 | $stripe_params['inline_cc_form'] = $this->inline_cc_form ? 'yes' : 'no'; |
||
| 568 | $stripe_params['stripe_checkout_require_billing_address'] = apply_filters( 'wc_stripe_checkout_require_billing_address', false ) ? 'yes' : 'no'; |
||
| 569 | $stripe_params['is_checkout'] = ( is_checkout() && empty( $_GET['pay_for_order'] ) ); |
||
| 570 | $stripe_params['return_url'] = $this->get_stripe_return_url(); |
||
| 571 | $stripe_params['ajaxurl'] = WC_AJAX::get_endpoint( '%%endpoint%%' ); |
||
| 572 | $stripe_params['stripe_nonce'] = wp_create_nonce( '_wc_stripe_nonce' ); |
||
| 573 | $stripe_params['statement_descriptor'] = $this->statement_descriptor; |
||
| 574 | $stripe_params['use_elements'] = apply_filters( 'wc_stripe_use_elements_checkout_form', true ) ? 'yes' : 'no'; |
||
| 575 | $stripe_params['is_stripe_checkout'] = $this->stripe_checkout ? 'yes' : 'no'; |
||
| 576 | $stripe_params['is_change_payment_page'] = ( isset( $_GET['pay_for_order'] ) || isset( $_GET['change_payment_method'] ) ) ? 'yes' : 'no'; |
||
| 577 | $stripe_params['elements_styling'] = apply_filters( 'wc_stripe_elements_styling', false ); |
||
| 578 | $stripe_params['elements_classes'] = apply_filters( 'wc_stripe_elements_classes', false ); |
||
| 579 | |||
| 580 | // merge localized messages to be use in JS |
||
| 581 | $stripe_params = array_merge( $stripe_params, WC_Stripe_Helper::get_localized_messages() ); |
||
| 582 | |||
| 583 | wp_localize_script( 'woocommerce_stripe', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) ); |
||
| 584 | wp_localize_script( 'woocommerce_stripe_checkout', 'wc_stripe_params', apply_filters( 'wc_stripe_params', $stripe_params ) ); |
||
| 585 | |||
| 586 | if ( $this->stripe_checkout ) { |
||
| 587 | wp_enqueue_script( 'stripe_checkout' ); |
||
| 588 | } |
||
| 589 | |||
| 590 | $this->tokenization_script(); |
||
| 591 | wp_enqueue_script( 'woocommerce_stripe' ); |
||
| 592 | } |
||
| 593 | |||
| 594 | /** |
||
| 595 | * Creates the 3DS source for charge. |
||
| 596 | * |
||
| 597 | * @since 4.0.0 |
||
| 598 | * @version 4.0.0 |
||
| 599 | * @param object $order |
||
| 600 | * @param object $source_object |
||
| 601 | * @return mixed |
||
| 602 | */ |
||
| 603 | public function create_3ds_source( $order, $source_object ) { |
||
| 604 | $currency = WC_Stripe_Helper::is_pre_30() ? $order->get_order_currency() : $order->get_currency(); |
||
| 605 | $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id(); |
||
|
0 ignored issues
–
show
$order_id is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the Loading history...
|
|||
| 606 | $return_url = $this->get_stripe_return_url( $order ); |
||
| 607 | |||
| 608 | $post_data = array(); |
||
| 609 | $post_data['amount'] = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $currency ); |
||
| 610 | $post_data['currency'] = strtolower( $currency ); |
||
| 611 | $post_data['type'] = 'three_d_secure'; |
||
| 612 | $post_data['owner'] = $this->get_owner_details( $order ); |
||
| 613 | $post_data['three_d_secure'] = array( 'card' => $source_object->id ); |
||
| 614 | $post_data['redirect'] = array( 'return_url' => $return_url ); |
||
| 615 | |||
| 616 | WC_Stripe_Logger::log( 'Info: Begin creating 3DS source' ); |
||
| 617 | |||
| 618 | return WC_Stripe_API::request( $post_data, 'sources' ); |
||
| 619 | } |
||
| 620 | |||
| 621 | /** |
||
| 622 | * Process the payment |
||
| 623 | * |
||
| 624 | * @since 1.0.0 |
||
| 625 | * @version 4.0.0 |
||
| 626 | * @param int $order_id Reference. |
||
| 627 | * @param bool $retry Should we retry on fail. |
||
| 628 | * @param bool $force_save_source Force save the payment source. |
||
| 629 | * |
||
| 630 | * @throws Exception If payment will not be accepted. |
||
| 631 | * |
||
| 632 | * @return array|void |
||
| 633 | */ |
||
| 634 | public function process_payment( $order_id, $retry = true, $force_save_source = false ) { |
||
| 635 | try { |
||
| 636 | $order = wc_get_order( $order_id ); |
||
| 637 | $source_object = ! empty( $_POST['stripe_source'] ) ? json_decode( wc_clean( stripslashes( $_POST['stripe_source'] ) ) ) : false; |
||
| 638 | |||
| 639 | // This comes from the create account checkbox in the checkout page. |
||
| 640 | $create_account = ! empty( $_POST['createaccount'] ) ? true : false; |
||
| 641 | |||
| 642 | if ( $create_account ) { |
||
| 643 | $new_customer_id = WC_Stripe_Helper::is_pre_30() ? $order->customer_user : $order->get_customer_id(); |
||
| 644 | $new_stripe_customer = new WC_Stripe_Customer( $new_customer_id ); |
||
| 645 | $new_stripe_customer->create_customer(); |
||
| 646 | } |
||
| 647 | |||
| 648 | $prepared_source = $this->prepare_source( get_current_user_id(), $force_save_source ); |
||
| 649 | |||
| 650 | // Check if we don't allow prepaid credit cards. |
||
| 651 | if ( ! apply_filters( 'wc_stripe_allow_prepaid_card', true ) ) { |
||
| 652 | $stripe_checkout_object = ! empty( $_POST['stripe_checkout_object'] ) ? json_decode( wc_clean( stripslashes( $_POST['stripe_checkout_object'] ) ) ) : false; |
||
| 653 | |||
| 654 | if ( $stripe_checkout_object && 'token' === $stripe_checkout_object->object && 'prepaid' === $stripe_checkout_object->card->funding ) { |
||
| 655 | $error_msg = __( 'Sorry, we\'re not accepting prepaid cards at this time. Your credit card has not been charge. Please try with alternative payment method.', 'woocommerce-gateway-stripe' ); |
||
| 656 | throw new Exception( $error_msg ); |
||
| 657 | } |
||
| 658 | } |
||
| 659 | |||
| 660 | if ( empty( $prepared_source->source ) ) { |
||
| 661 | $error_msg = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' ); |
||
| 662 | throw new Exception( $error_msg ); |
||
| 663 | } |
||
| 664 | |||
| 665 | // Store source to order meta. |
||
| 666 | $this->save_source( $order, $prepared_source ); |
||
| 667 | |||
| 668 | // Result from Stripe API request. |
||
| 669 | $response = null; |
||
| 670 | |||
| 671 | if ( $order->get_total() > 0 ) { |
||
| 672 | // This will throw exception if not valid. |
||
| 673 | $this->validate_minimum_order_amount( $order ); |
||
| 674 | |||
| 675 | /** |
||
| 676 | * Check if card 3DS is required or optional with 3DS setting. |
||
| 677 | * Will need to first create 3DS source and require redirection |
||
| 678 | * for customer to login to their credit card company. |
||
| 679 | * Note that if we need to save source, the original source must be first |
||
| 680 | * attached to a customer in Stripe before it can be charged. |
||
| 681 | */ |
||
| 682 | if ( $source_object && ( 'card' === $source_object->type && 'required' === $source_object->card->three_d_secure || ( $this->three_d_secure && 'optional' === $source_object->card->three_d_secure ) ) ) { |
||
| 683 | |||
| 684 | $response = $this->create_3ds_source( $order, $source_object ); |
||
| 685 | |||
| 686 | if ( ! empty( $response->error ) ) { |
||
| 687 | $message = $response->error->message; |
||
| 688 | |||
| 689 | $order->add_order_note( $message ); |
||
| 690 | |||
| 691 | throw new Exception( $message ); |
||
| 692 | } |
||
| 693 | |||
| 694 | // Update order meta with 3DS source. |
||
| 695 | if ( WC_Stripe_Helper::is_pre_30() ) { |
||
| 696 | update_post_meta( $order_id, '_stripe_source_id', $response->id ); |
||
| 697 | } else { |
||
| 698 | $order->update_meta_data( '_stripe_source_id', $response->id ); |
||
| 699 | $order->save(); |
||
| 700 | } |
||
| 701 | |||
| 702 | WC_Stripe_Logger::log( 'Info: Redirecting to 3DS...' ); |
||
| 703 | |||
| 704 | return array( |
||
| 705 | 'result' => 'success', |
||
| 706 | 'redirect' => esc_url_raw( $response->redirect->url ), |
||
| 707 | ); |
||
| 708 | } |
||
| 709 | |||
| 710 | WC_Stripe_Logger::log( "Info: Begin processing payment for order $order_id for the amount of {$order->get_total()}" ); |
||
| 711 | |||
| 712 | // Make the request. |
||
| 713 | $response = WC_Stripe_API::request( $this->generate_payment_request( $order, $prepared_source ) ); |
||
| 714 | |||
| 715 | if ( ! empty( $response->error ) ) { |
||
| 716 | // If it is an API error such connection or server, let's retry. |
||
| 717 | if ( 'api_connection_error' === $response->error->type || 'api_error' === $response->error->type ) { |
||
| 718 | if ( $retry ) { |
||
| 719 | sleep( 5 ); |
||
| 720 | return $this->process_payment( $order_id, false, $force_save_source ); |
||
| 721 | } else { |
||
| 722 | $message = 'API connection error and retries exhausted.'; |
||
| 723 | $order->add_order_note( $message ); |
||
| 724 | throw new Exception( $message ); |
||
| 725 | } |
||
| 726 | } |
||
| 727 | |||
| 728 | // Customer param wrong? The user may have been deleted on stripe's end. Remove customer_id. Can be retried without. |
||
| 729 | if ( preg_match( '/No such customer/i', $response->error->message ) && $retry ) { |
||
| 730 | delete_user_meta( WC_Stripe_Helper::is_pre_30() ? $order->customer_user : $order->get_customer_id(), '_stripe_customer_id' ); |
||
| 731 | |||
| 732 | return $this->process_payment( $order_id, false, $force_save_source ); |
||
| 733 | } elseif ( preg_match( '/No such token/i', $response->error->message ) && $prepared_source->token_id ) { |
||
| 734 | // Source param wrong? The CARD may have been deleted on stripe's end. Remove token and show message. |
||
| 735 | $wc_token = WC_Payment_Tokens::get( $prepared_source->token_id ); |
||
| 736 | $wc_token->delete(); |
||
| 737 | $message = __( 'This card is no longer available and has been removed.', 'woocommerce-gateway-stripe' ); |
||
| 738 | $order->add_order_note( $message ); |
||
| 739 | throw new Exception( $message ); |
||
| 740 | } |
||
| 741 | |||
| 742 | $localized_messages = WC_Stripe_Helper::get_localized_messages(); |
||
| 743 | |||
| 744 | $message = isset( $localized_messages[ $response->error->type ] ) ? $localized_messages[ $response->error->type ] : $response->error->message; |
||
| 745 | |||
| 746 | $order->add_order_note( $message ); |
||
| 747 | |||
| 748 | throw new Exception( $message ); |
||
| 749 | } |
||
| 750 | |||
| 751 | do_action( 'wc_gateway_stripe_process_payment', $response, $order ); |
||
| 752 | |||
| 753 | // Process valid response. |
||
| 754 | $this->process_response( $response, $order ); |
||
| 755 | } else { |
||
| 756 | $order->payment_complete(); |
||
| 757 | } |
||
| 758 | |||
| 759 | // Remove cart. |
||
| 760 | WC()->cart->empty_cart(); |
||
| 761 | |||
| 762 | // Return thank you page redirect. |
||
| 763 | return array( |
||
| 764 | 'result' => 'success', |
||
| 765 | 'redirect' => $this->get_return_url( $order ), |
||
| 766 | ); |
||
| 767 | |||
| 768 | } catch ( Exception $e ) { |
||
| 769 | wc_add_notice( $e->getMessage(), 'error' ); |
||
| 770 | WC_Stripe_Logger::log( 'Error: ' . $e->getMessage() ); |
||
| 771 | |||
| 772 | do_action( 'wc_gateway_stripe_process_payment_error', $e, $order ); |
||
| 773 | |||
| 774 | if ( $order->has_status( array( 'pending', 'failed' ) ) ) { |
||
| 775 | $this->send_failed_order_email( $order_id ); |
||
| 776 | } |
||
| 777 | |||
| 778 | return array( |
||
| 779 | 'result' => 'fail', |
||
| 780 | 'redirect' => '', |
||
| 781 | ); |
||
| 782 | } |
||
| 783 | } |
||
| 784 | } |
||
| 785 |
This check looks for assignments to scalar types that may be of the wrong type.
To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.