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 | * Compatibility class for Subscriptions and Pre-Orders. |
||
| 8 | * |
||
| 9 | * @extends WC_Gateway_Stripe_Sepa |
||
| 10 | */ |
||
| 11 | View Code Duplication | class WC_Stripe_Sepa_Compat extends WC_Gateway_Stripe_Sepa { |
|
|
0 ignored issues
–
show
|
|||
| 12 | /** |
||
| 13 | * Constructor |
||
| 14 | */ |
||
| 15 | public function __construct() { |
||
| 16 | parent::__construct(); |
||
| 17 | |||
| 18 | if ( class_exists( 'WC_Subscriptions_Order' ) ) { |
||
| 19 | add_action( 'woocommerce_scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 2 ); |
||
| 20 | add_action( 'wcs_resubscribe_order_created', array( $this, 'delete_resubscribe_meta' ), 10 ); |
||
| 21 | add_action( 'wcs_renewal_order_created', array( $this, 'delete_renewal_meta' ), 10 ); |
||
| 22 | add_action( 'woocommerce_subscription_failing_payment_method_updated_stripe', array( $this, 'update_failing_payment_method' ), 10, 2 ); |
||
| 23 | |||
| 24 | // display the credit card used for a subscription in the "My Subscriptions" table |
||
| 25 | add_filter( 'woocommerce_my_subscriptions_payment_method', array( $this, 'maybe_render_subscription_payment_method' ), 10, 2 ); |
||
| 26 | |||
| 27 | // allow store managers to manually set Stripe as the payment method on a subscription |
||
| 28 | add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 ); |
||
| 29 | add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 ); |
||
| 30 | add_filter( 'wc_stripe_display_save_payment_method_checkbox', array( $this, 'maybe_hide_save_checkbox' ) ); |
||
| 31 | add_filter( 'wc_stripe_payment_metadata', array( $this, 'add_subscription_meta_data' ), 10, 2 ); |
||
| 32 | } |
||
| 33 | |||
| 34 | if ( class_exists( 'WC_Pre_Orders_Order' ) ) { |
||
| 35 | add_action( 'wc_pre_orders_process_pre_order_completion_payment_' . $this->id, array( $this, 'process_pre_order_release_payment' ) ); |
||
| 36 | } |
||
| 37 | } |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Checks to see if we need to hide the save checkbox field. |
||
| 41 | * Because when cart contains a subs product, it will save regardless. |
||
| 42 | * |
||
| 43 | * @since 4.0.0 |
||
| 44 | * @version 4.0.0 |
||
| 45 | */ |
||
| 46 | public function maybe_hide_save_checkbox( $display_tokenization ) { |
||
| 47 | if ( WC_Subscriptions_Cart::cart_contains_subscription() ) { |
||
| 48 | return false; |
||
| 49 | } |
||
| 50 | |||
| 51 | return $display_tokenization; |
||
| 52 | } |
||
| 53 | |||
| 54 | /** |
||
| 55 | * Is $order_id a subscription? |
||
| 56 | * @param int $order_id |
||
| 57 | * @return boolean |
||
| 58 | */ |
||
| 59 | public function has_subscription( $order_id ) { |
||
| 60 | return ( function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_is_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) ) ); |
||
| 61 | } |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Is $order_id a pre-order? |
||
| 65 | * @param int $order_id |
||
| 66 | * @return boolean |
||
| 67 | */ |
||
| 68 | protected function is_pre_order( $order_id ) { |
||
| 69 | return ( class_exists( 'WC_Pre_Orders_Order' ) && WC_Pre_Orders_Order::order_contains_pre_order( $order_id ) ); |
||
| 70 | } |
||
| 71 | |||
| 72 | /** |
||
| 73 | * Process the payment based on type. |
||
| 74 | * @param int $order_id |
||
| 75 | * @return array |
||
| 76 | */ |
||
| 77 | public function process_payment( $order_id, $retry = true, $force_save_source = false ) { |
||
| 78 | if ( $this->has_subscription( $order_id ) ) { |
||
| 79 | // Regular payment with force customer enabled |
||
| 80 | return parent::process_payment( $order_id, true, true ); |
||
| 81 | } elseif ( $this->is_pre_order( $order_id ) ) { |
||
| 82 | return $this->process_pre_order( $order_id, $retry, $force_save_source ); |
||
| 83 | } else { |
||
| 84 | return parent::process_payment( $order_id, $retry, $force_save_source ); |
||
| 85 | } |
||
| 86 | } |
||
| 87 | |||
| 88 | /** |
||
| 89 | * Adds subscription related meta data on charge request. |
||
| 90 | * |
||
| 91 | * @since 4.0.0 |
||
| 92 | * @param array $metadata |
||
| 93 | * @param object $order |
||
| 94 | */ |
||
| 95 | public function add_subscription_meta_data( $metadata, $order ) { |
||
| 96 | if ( ! $this->has_subscription( $order->get_id() ) ) { |
||
| 97 | return $metadata; |
||
| 98 | } |
||
| 99 | |||
| 100 | return $metadata += array( |
||
| 101 | 'payment_type' => 'recurring', |
||
| 102 | 'site_url' => esc_url( get_site_url() ), |
||
| 103 | ); |
||
| 104 | } |
||
| 105 | |||
| 106 | /** |
||
| 107 | * Updates other subscription sources. |
||
| 108 | * |
||
| 109 | * @since 3.1.0 |
||
| 110 | * @version 4.0.0 |
||
| 111 | */ |
||
| 112 | public function save_source( $order, $source ) { |
||
| 113 | parent::save_source( $order, $source ); |
||
| 114 | |||
| 115 | $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id(); |
||
| 116 | |||
| 117 | // Also store it on the subscriptions being purchased or paid for in the order |
||
| 118 | if ( function_exists( 'wcs_order_contains_subscription' ) && wcs_order_contains_subscription( $order_id ) ) { |
||
| 119 | $subscriptions = wcs_get_subscriptions_for_order( $order_id ); |
||
| 120 | } elseif ( function_exists( 'wcs_order_contains_renewal' ) && wcs_order_contains_renewal( $order_id ) ) { |
||
| 121 | $subscriptions = wcs_get_subscriptions_for_renewal_order( $order_id ); |
||
| 122 | } else { |
||
| 123 | $subscriptions = array(); |
||
| 124 | } |
||
| 125 | |||
| 126 | foreach ( $subscriptions as $subscription ) { |
||
| 127 | $subscription_id = WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id(); |
||
| 128 | update_post_meta( $subscription_id, '_stripe_customer_id', $source->customer ); |
||
| 129 | update_post_meta( $subscription_id, '_stripe_source_id', $source->source ); |
||
| 130 | } |
||
| 131 | } |
||
| 132 | |||
| 133 | /** |
||
| 134 | * process_subscription_payment function. |
||
| 135 | * @param mixed $order |
||
| 136 | * @param int $amount (default: 0) |
||
| 137 | * @param string $stripe_token (default: '') |
||
|
0 ignored issues
–
show
There is no parameter named
$stripe_token. Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. Loading history...
|
|||
| 138 | * @param bool initial_payment |
||
| 139 | */ |
||
| 140 | public function process_subscription_payment( $order = '', $amount = 0 ) { |
||
| 141 | if ( $amount * 100 < WC_Stripe_Helper::get_minimum_amount() ) { |
||
| 142 | /* translators: minimum amount */ |
||
| 143 | return new WP_Error( 'stripe_error', sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe_Helper::get_minimum_amount() / 100 ) ) ); |
||
| 144 | } |
||
| 145 | |||
| 146 | $customer_id = WC_Stripe_Helper::is_pre_30() ? $order->customer_user : $order->get_customer_id(); |
||
|
0 ignored issues
–
show
$customer_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...
|
|||
| 147 | $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id(); |
||
| 148 | |||
| 149 | // Get source from order |
||
| 150 | $prepared_source = $this->prepare_order_source( $order ); |
||
| 151 | |||
| 152 | // Or fail :( |
||
|
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. Loading history...
|
|||
| 153 | if ( ! $prepared_source->customer ) { |
||
| 154 | return new WP_Error( 'stripe_error', __( 'Customer not found', 'woocommerce-gateway-stripe' ) ); |
||
| 155 | } |
||
| 156 | |||
| 157 | WC_Stripe_Logger::log( "Info: Begin processing subscription payment for order {$order_id} for the amount of {$amount}" ); |
||
| 158 | |||
| 159 | // Make the request |
||
| 160 | $request = $this->generate_payment_request( $order, $prepared_source ); |
||
| 161 | $request['capture'] = 'true'; |
||
| 162 | $request['amount'] = WC_Stripe_Helper::get_stripe_amount( $amount, $request['currency'] ); |
||
| 163 | $response = WC_Stripe_API::request( $request ); |
||
| 164 | |||
| 165 | // Process valid response |
||
| 166 | if ( ! empty( $response->error ) ) { |
||
| 167 | return $response; // Default catch all errors. |
||
| 168 | } |
||
| 169 | |||
| 170 | $this->process_response( $response, $order ); |
||
| 171 | |||
| 172 | return $response; |
||
| 173 | } |
||
| 174 | |||
| 175 | /** |
||
| 176 | * Don't transfer Stripe customer/token meta to resubscribe orders. |
||
| 177 | * @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription |
||
| 178 | */ |
||
| 179 | public function delete_resubscribe_meta( $resubscribe_order ) { |
||
| 180 | delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_customer_id' ); |
||
|
0 ignored issues
–
show
|
|||
| 181 | delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_source_id' ); |
||
|
0 ignored issues
–
show
|
|||
| 182 | // For BW compat will remove in future |
||
| 183 | delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $resubscribe_order->id : $resubscribe_order->get_id() ), '_stripe_card_id' ); |
||
|
0 ignored issues
–
show
|
|||
| 184 | $this->delete_renewal_meta( $resubscribe_order ); |
||
| 185 | } |
||
| 186 | |||
| 187 | /** |
||
| 188 | * Don't transfer Stripe fee/ID meta to renewal orders. |
||
| 189 | * @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription |
||
|
0 ignored issues
–
show
There is no parameter named
$resubscribe_order. Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. Loading history...
|
|||
| 190 | */ |
||
| 191 | public function delete_renewal_meta( $renewal_order ) { |
||
| 192 | delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $renewal_order->id : $renewal_order->get_id() ), 'Stripe Fee' ); |
||
| 193 | delete_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $renewal_order->id : $renewal_order->get_id() ), 'Net Revenue From Stripe' ); |
||
| 194 | return $renewal_order; |
||
| 195 | } |
||
| 196 | |||
| 197 | /** |
||
| 198 | * scheduled_subscription_payment function. |
||
| 199 | * |
||
| 200 | * @param $amount_to_charge float The amount to charge. |
||
| 201 | * @param $renewal_order WC_Order A WC_Order object created to record the renewal payment. |
||
| 202 | */ |
||
| 203 | public function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) { |
||
| 204 | $response = $this->process_subscription_payment( $renewal_order, $amount_to_charge ); |
||
| 205 | |||
| 206 | if ( is_wp_error( $response ) ) { |
||
| 207 | /* translators: error message */ |
||
| 208 | $renewal_order->update_status( 'failed', sprintf( __( 'Stripe Transaction Failed (%s)', 'woocommerce-gateway-stripe' ), $response->get_error_message() ) ); |
||
| 209 | } |
||
| 210 | |||
| 211 | if ( ! empty( $response->error ) ) { |
||
| 212 | /* translators: error message */ |
||
| 213 | $renewal_order->update_status( 'failed', sprintf( __( 'Stripe Transaction Failed (%s)', 'woocommerce-gateway-stripe' ), $response->error->message ) ); |
||
| 214 | } |
||
| 215 | } |
||
| 216 | |||
| 217 | /** |
||
| 218 | * Remove order meta |
||
| 219 | * @param object $order |
||
| 220 | */ |
||
| 221 | public function remove_order_source_before_retry( $order ) { |
||
| 222 | $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id(); |
||
| 223 | delete_post_meta( $order_id, '_stripe_source_id' ); |
||
| 224 | // For BW compat will remove in the future. |
||
| 225 | delete_post_meta( $order_id, '_stripe_card_id' ); |
||
| 226 | } |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Remove order meta |
||
| 230 | * @param object $order |
||
| 231 | */ |
||
| 232 | public function remove_order_customer_before_retry( $order ) { |
||
| 233 | $order_id = WC_Stripe_Helper::is_pre_30() ? $order->id : $order->get_id(); |
||
| 234 | delete_post_meta( $order_id, '_stripe_customer_id' ); |
||
| 235 | } |
||
| 236 | |||
| 237 | /** |
||
| 238 | * Update the customer_id for a subscription after using Stripe to complete a payment to make up for |
||
| 239 | * an automatic renewal payment which previously failed. |
||
| 240 | * |
||
| 241 | * @access public |
||
| 242 | * @param WC_Subscription $subscription The subscription for which the failing payment method relates. |
||
| 243 | * @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment). |
||
| 244 | * @return void |
||
| 245 | */ |
||
| 246 | public function update_failing_payment_method( $subscription, $renewal_order ) { |
||
| 247 | if ( WC_Stripe_Helper::is_pre_30() ) { |
||
| 248 | update_post_meta( $subscription->id, '_stripe_customer_id', $renewal_order->stripe_customer_id ); |
||
| 249 | update_post_meta( $subscription->id, '_stripe_source_id', $renewal_order->stripe_source_id ); |
||
| 250 | |||
| 251 | } else { |
||
| 252 | update_post_meta( $subscription->get_id(), '_stripe_customer_id', $renewal_order->get_meta( '_stripe_customer_id', true ) ); |
||
| 253 | update_post_meta( $subscription->get_id(), '_stripe_source_id', $renewal_order->get_meta( '_stripe_source_id', true ) ); |
||
| 254 | } |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Include the payment meta data required to process automatic recurring payments so that store managers can |
||
| 259 | * manually set up automatic recurring payments for a customer via the Edit Subscriptions screen in 2.0+. |
||
| 260 | * |
||
| 261 | * @since 2.5 |
||
| 262 | * @param array $payment_meta associative array of meta data required for automatic payments |
||
| 263 | * @param WC_Subscription $subscription An instance of a subscription object |
||
| 264 | * @return array |
||
| 265 | */ |
||
| 266 | public function add_subscription_payment_meta( $payment_meta, $subscription ) { |
||
| 267 | $source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_source_id', true ); |
||
| 268 | |||
| 269 | // For BW compat will remove in future. |
||
| 270 | if ( empty( $source_id ) ) { |
||
| 271 | $source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_card_id', true ); |
||
| 272 | |||
| 273 | // Take this opportunity to update the key name. |
||
| 274 | WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->id, '_stripe_source_id', $source_id ) : update_post_meta( $subscription->get_id(), '_stripe_source_id', $source_id ); |
||
| 275 | } |
||
| 276 | |||
| 277 | $payment_meta[ $this->id ] = array( |
||
| 278 | 'post_meta' => array( |
||
| 279 | '_stripe_customer_id' => array( |
||
| 280 | 'value' => get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_customer_id', true ), |
||
| 281 | 'label' => 'Stripe Customer ID', |
||
| 282 | ), |
||
| 283 | '_stripe_source_id' => array( |
||
| 284 | 'value' => $source_id, |
||
| 285 | 'label' => 'Stripe Source ID', |
||
| 286 | ), |
||
| 287 | ), |
||
| 288 | ); |
||
| 289 | return $payment_meta; |
||
| 290 | } |
||
| 291 | |||
| 292 | /** |
||
| 293 | * Validate the payment meta data required to process automatic recurring payments so that store managers can |
||
| 294 | * manually set up automatic recurring payments for a customer via the Edit Subscriptions screen in 2.0+. |
||
| 295 | * |
||
| 296 | * @since 2.5 |
||
| 297 | * @param string $payment_method_id The ID of the payment method to validate |
||
| 298 | * @param array $payment_meta associative array of meta data required for automatic payments |
||
| 299 | * @return array |
||
| 300 | */ |
||
| 301 | public function validate_subscription_payment_meta( $payment_method_id, $payment_meta ) { |
||
| 302 | if ( $this->id === $payment_method_id ) { |
||
| 303 | |||
| 304 | if ( ! isset( $payment_meta['post_meta']['_stripe_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_stripe_customer_id']['value'] ) ) { |
||
| 305 | throw new Exception( 'A "_stripe_customer_id" value is required.' ); |
||
| 306 | } elseif ( 0 !== strpos( $payment_meta['post_meta']['_stripe_customer_id']['value'], 'cus_' ) ) { |
||
| 307 | throw new Exception( 'Invalid customer ID. A valid "_stripe_customer_id" must begin with "cus_".' ); |
||
| 308 | } |
||
| 309 | |||
| 310 | if ( ! isset( $payment_meta['post_meta']['_stripe_source_id']['value'] ) || empty( $payment_meta['post_meta']['_stripe_source_id']['value'] ) ) { |
||
| 311 | throw new Exception( 'A "_stripe_source_id" value is required.' ); |
||
| 312 | } |
||
| 313 | } |
||
| 314 | } |
||
| 315 | |||
| 316 | /** |
||
| 317 | * Render the payment method used for a subscription in the "My Subscriptions" table |
||
| 318 | * |
||
| 319 | * @since 1.7.5 |
||
| 320 | * @param string $payment_method_to_display the default payment method text to display |
||
| 321 | * @param WC_Subscription $subscription the subscription details |
||
| 322 | * @return string the subscription payment method |
||
| 323 | */ |
||
| 324 | public function maybe_render_subscription_payment_method( $payment_method_to_display, $subscription ) { |
||
| 325 | $customer_user = WC_Stripe_Helper::is_pre_30() ? $subscription->customer_user : $subscription->get_customer_id(); |
||
| 326 | |||
| 327 | // bail for other payment methods |
||
| 328 | if ( ( WC_Stripe_Helper::is_pre_30() ? $subscription->payment_method : $subscription->get_payment_method() ) !== $this->id || ! $customer_user ) { |
||
| 329 | return $payment_method_to_display; |
||
| 330 | } |
||
| 331 | |||
| 332 | $stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_source_id', true ); |
||
| 333 | |||
| 334 | // For BW compat will remove in future. |
||
| 335 | if ( empty( $stripe_source_id ) ) { |
||
| 336 | $stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_card_id', true ); |
||
| 337 | |||
| 338 | // Take this opportunity to update the key name. |
||
| 339 | WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->id, '_stripe_source_id', $stripe_source_id ) : update_post_meta( $subscription->get_id(), '_stripe_source_id', $stripe_source_id ); |
||
| 340 | } |
||
| 341 | |||
| 342 | $stripe_customer = new WC_Stripe_Customer(); |
||
| 343 | $stripe_customer_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->id : $subscription->get_id() ), '_stripe_customer_id', true ); |
||
| 344 | |||
| 345 | // If we couldn't find a Stripe customer linked to the subscription, fallback to the user meta data. |
||
| 346 | if ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) { |
||
| 347 | $user_id = $customer_user; |
||
| 348 | $stripe_customer_id = get_user_meta( $user_id, '_stripe_customer_id', true ); |
||
| 349 | $stripe_source_id = get_user_meta( $user_id, '_stripe_source_id', true ); |
||
| 350 | |||
| 351 | // For BW compat will remove in future. |
||
| 352 | if ( empty( $stripe_source_id ) ) { |
||
| 353 | $stripe_source_id = get_user_meta( $user_id, '_stripe_card_id', true ); |
||
| 354 | |||
| 355 | // Take this opportunity to update the key name. |
||
| 356 | update_user_meta( $user_id, '_stripe_source_id', $stripe_source_id ); |
||
| 357 | } |
||
| 358 | } |
||
| 359 | |||
| 360 | // If we couldn't find a Stripe customer linked to the account, fallback to the order meta data. |
||
| 361 | if ( ( ! $stripe_customer_id || ! is_string( $stripe_customer_id ) ) && false !== $subscription->order ) { |
||
| 362 | $stripe_customer_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_customer_id', true ); |
||
| 363 | $stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_source_id', true ); |
||
| 364 | |||
| 365 | // For BW compat will remove in future. |
||
| 366 | if ( empty( $stripe_source_id ) ) { |
||
| 367 | $stripe_source_id = get_post_meta( ( WC_Stripe_Helper::is_pre_30() ? $subscription->order->id : $subscription->get_parent_id() ), '_stripe_card_id', true ); |
||
| 368 | |||
| 369 | // Take this opportunity to update the key name. |
||
| 370 | WC_Stripe_Helper::is_pre_30() ? update_post_meta( $subscription->order->id, '_stripe_source_id', $stripe_source_id ) : update_post_meta( $subscription->get_parent_id(), '_stripe_source_id', $stripe_source_id ); |
||
| 371 | } |
||
| 372 | } |
||
| 373 | |||
| 374 | $stripe_customer->set_id( $stripe_customer_id ); |
||
| 375 | $sources = $stripe_customer->get_sources(); |
||
| 376 | |||
| 377 | if ( $sources ) { |
||
|
0 ignored issues
–
show
The expression
$sources of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using Loading history...
|
|||
| 378 | $found_source = false; |
||
| 379 | foreach ( $sources as $source ) { |
||
| 380 | if ( isset( $source->type ) && 'card' === $source->type ) { |
||
| 381 | $card = $source->card; |
||
| 382 | } |
||
| 383 | |||
| 384 | if ( $source->id === $stripe_source_id ) { |
||
| 385 | $found_source = true; |
||
| 386 | /* translators: 1) card brand 2) last 4 digits */ |
||
| 387 | $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 ); |
||
|
0 ignored issues
–
show
The variable
$card does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
| 388 | break; |
||
| 389 | } |
||
| 390 | } |
||
| 391 | |||
| 392 | if ( ! $found_source ) { |
||
| 393 | if ( 'card' === $sources[0]->type ) { |
||
| 394 | $card = $sources[0]->card; |
||
| 395 | } |
||
| 396 | |||
| 397 | /* translators: 1) card brand 2) last 4 digits */ |
||
| 398 | $payment_method_to_display = sprintf( __( 'Via %1$s card ending in %2$s', 'woocommerce-gateway-stripe' ), ( isset( $card->brand ) ? $card->brand : __( 'N/A', 'woocommerce-gateway-stripe' ) ), $card->last4 ); |
||
| 399 | } |
||
| 400 | } |
||
| 401 | |||
| 402 | return $payment_method_to_display; |
||
| 403 | } |
||
| 404 | |||
| 405 | /** |
||
| 406 | * Process the pre-order |
||
| 407 | * @param int $order_id |
||
| 408 | * @return array |
||
| 409 | */ |
||
| 410 | public function process_pre_order( $order_id, $retry, $force_save_source ) { |
||
| 411 | if ( WC_Pre_Orders_Order::order_requires_payment_tokenization( $order_id ) ) { |
||
| 412 | try { |
||
| 413 | $order = wc_get_order( $order_id ); |
||
| 414 | |||
| 415 | if ( $order->get_total() * 100 < WC_Stripe_Helper::get_minimum_amount() ) { |
||
| 416 | /* translators: minimum amount */ |
||
| 417 | throw new Exception( sprintf( __( 'Sorry, the minimum allowed order total is %1$s to use this payment method.', 'woocommerce-gateway-stripe' ), wc_price( WC_Stripe_Helper::get_minimum_amount() / 100 ) ) ); |
||
| 418 | } |
||
| 419 | |||
| 420 | $source = $this->prepare_source( get_current_user_id(), true ); |
||
| 421 | |||
| 422 | // We need a source on file to continue. |
||
| 423 | if ( empty( $source->customer ) || empty( $source->source ) ) { |
||
| 424 | throw new Exception( __( 'Unable to store payment details. Please try again.', 'woocommerce-gateway-stripe' ) ); |
||
| 425 | } |
||
| 426 | |||
| 427 | // Store source to order meta |
||
| 428 | $this->save_source( $order, $source ); |
||
| 429 | |||
| 430 | // Remove cart |
||
| 431 | WC()->cart->empty_cart(); |
||
| 432 | |||
| 433 | // Is pre ordered! |
||
| 434 | WC_Pre_Orders_Order::mark_order_as_pre_ordered( $order ); |
||
| 435 | |||
| 436 | // Return thank you page redirect |
||
| 437 | return array( |
||
| 438 | 'result' => 'success', |
||
| 439 | 'redirect' => $this->get_return_url( $order ), |
||
| 440 | ); |
||
| 441 | } catch ( Exception $e ) { |
||
| 442 | wc_add_notice( $e->getMessage(), 'error' ); |
||
| 443 | return; |
||
| 444 | } |
||
| 445 | } else { |
||
| 446 | return parent::process_payment( $order_id, $retry, $force_save_source ); |
||
|
0 ignored issues
–
show
It seems like you call parent on a different method (
process_payment() instead of process_pre_order()). Are you sure this is correct? If so, you might want to change this to $this->process_payment().
This check looks for a call to a parent method whose name is different than the method from which it is called. Consider the following code: class Daddy
{
protected function getFirstName()
{
return "Eidur";
}
protected function getSurName()
{
return "Gudjohnsen";
}
}
class Son
{
public function getFirstName()
{
return parent::getSurname();
}
}
The Loading history...
|
|||
| 447 | } |
||
| 448 | } |
||
| 449 | |||
| 450 | /** |
||
| 451 | * Process a pre-order payment when the pre-order is released |
||
| 452 | * @param WC_Order $order |
||
| 453 | * @return void |
||
| 454 | */ |
||
| 455 | public function process_pre_order_release_payment( $order ) { |
||
| 456 | try { |
||
| 457 | // Define some callbacks if the first attempt fails. |
||
| 458 | $retry_callbacks = array( |
||
| 459 | 'remove_order_source_before_retry', |
||
| 460 | 'remove_order_customer_before_retry', |
||
| 461 | ); |
||
| 462 | |||
| 463 | while ( 1 ) { |
||
| 464 | $source = $this->prepare_order_source( $order ); |
||
| 465 | $response = WC_Stripe_API::request( $this->generate_payment_request( $order, $source ) ); |
||
| 466 | |||
| 467 | if ( ! empty( $response->error ) ) { |
||
| 468 | if ( 0 === sizeof( $retry_callbacks ) ) { |
||
| 469 | throw new Exception( $response->error->message ); |
||
| 470 | } else { |
||
| 471 | $retry_callback = array_shift( $retry_callbacks ); |
||
| 472 | call_user_func( array( $this, $retry_callback ), $order ); |
||
| 473 | } |
||
| 474 | } else { |
||
| 475 | // Successful |
||
| 476 | $this->process_response( $response, $order ); |
||
| 477 | break; |
||
| 478 | } |
||
| 479 | } |
||
| 480 | } catch ( Exception $e ) { |
||
| 481 | /* translators: error message */ |
||
| 482 | $order_note = sprintf( __( 'Stripe Transaction Failed (%s)', 'woocommerce-gateway-stripe' ), $e->getMessage() ); |
||
| 483 | |||
| 484 | // Mark order as failed if not already set, |
||
| 485 | // otherwise, make sure we add the order note so we can detect when someone fails to check out multiple times |
||
| 486 | if ( ! $order->has_status( 'failed' ) ) { |
||
| 487 | $order->update_status( 'failed', $order_note ); |
||
| 488 | } else { |
||
| 489 | $order->add_order_note( $order_note ); |
||
| 490 | } |
||
| 491 | } |
||
| 492 | } |
||
| 493 | } |
||
| 494 |
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.