Support » Plugin: WooCommerce Stripe Payment Gateway » Manual order, depending on the product I have in the order

  • Resolved fagworio

    (@fagworio)


    Hello everybody.

    I would like to customize the stripe plug-in so that when an order has a specific product, it is saved but not billed immediately.

    In this case, I could analyze the order and if it met my requirements, I would do the direct process in woocommerce to change the status from On-hold to Processing.

    I know I have an option on stripe Capture charge immediately, but I don’t want this behavior for all products and only for those that meet my approval requirement.

    In short I am wanting to place a manual order, depending on the product I have in the order.

    I wonder if anyone can help me do something like that.

    I’ve already made a previous modification in this sense and it works on my testing site, but on the production site it always does the combing and changes it to Completed.

    Modified Code:

    I added this to this methood, to force this specific role be added as $capture = false

    // If have my requirements change $capture = false
    if( isset($_POST['oow_radio_fields']) ) {
        $capture = false;
    }
    public function generate_payment_request( $order, $prepared_source ) {
    		$settings              = get_option( 'woocommerce_stripe_settings', [] );
    		$statement_descriptor  = ! empty( $settings['statement_descriptor'] ) ? str_replace( "'", '', $settings['statement_descriptor'] ) : '';
    		$capture               = ! empty( $settings['capture'] ) && 'yes' === $settings['capture'] ? true : false;
    		$post_data             = [];
    		$post_data['currency'] = strtolower( $order->get_currency() );
    		$post_data['amount']   = WC_Stripe_Helper::get_stripe_amount( $order->get_total(), $post_data['currency'] );
    		/* translators: 1) blog name 2) order number */
    		$post_data['description'] = sprintf( __( '%1$s - Order %2$s', 'woocommerce-gateway-stripe' ), wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ), $order->get_order_number() );
    		$billing_email            = $order->get_billing_email();
    		$billing_first_name       = $order->get_billing_first_name();
    		$billing_last_name        = $order->get_billing_last_name();
    
    		if ( ! empty( $billing_email ) && apply_filters( 'wc_stripe_send_stripe_receipt', false ) ) {
    			$post_data['receipt_email'] = $billing_email;
    		}
                    // If have my requirements change $capture = false
    		if( isset($_POST['oow_radio_fields']) ) {
    			$capture = false;
    		}
    
    		switch ( $order->get_payment_method() ) {
    			case 'stripe':
    				if ( ! empty( $statement_descriptor ) ) {
    					$post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $statement_descriptor );
    				}
    
    				$post_data['capture'] = $capture ? 'true' : 'false';
    				break;
    			case 'stripe_sepa':
    				if ( ! empty( $statement_descriptor ) ) {
    					$post_data['statement_descriptor'] = WC_Stripe_Helper::clean_statement_descriptor( $statement_descriptor );
    				}
    				break;
    		}
    
    	
    	
    
    		if ( method_exists( $order, 'get_shipping_postcode' ) && ! empty( $order->get_shipping_postcode() ) ) {
    			$post_data['shipping'] = [
    				'name'    => trim( $order->get_shipping_first_name() . ' ' . $order->get_shipping_last_name() ),
    				'address' => [
    					'line1'       => $order->get_shipping_address_1(),
    					'line2'       => $order->get_shipping_address_2(),
    					'city'        => $order->get_shipping_city(),
    					'country'     => $order->get_shipping_country(),
    					'postal_code' => $order->get_shipping_postcode(),
    					'state'       => $order->get_shipping_state(),
    				],
    			];
    		}
    
    		$post_data['expand[]'] = 'balance_transaction';
    
    		$metadata = [
    			__( 'customer_name', 'woocommerce-gateway-stripe' ) => sanitize_text_field( $billing_first_name ) . ' ' . sanitize_text_field( $billing_last_name ),
    			__( 'customer_email', 'woocommerce-gateway-stripe' ) => sanitize_email( $billing_email ),
    			'order_id' => $order->get_order_number(),
    			'site_url' => esc_url( get_site_url() ),
    		];
    
    		if ( $this->has_subscription( $order->get_id() ) ) {
    			$metadata += [
    				'payment_type' => 'recurring',
    			];
    		}
    
    		$post_data['metadata'] = apply_filters( 'wc_stripe_payment_metadata', $metadata, $order, $prepared_source );
    
    		if ( $prepared_source->customer ) {
    			$post_data['customer'] = $prepared_source->customer;
    		}
    
    		if ( $prepared_source->source ) {
    			$post_data['source'] = $prepared_source->source;
    		}
    
    		/**
    		 * Filter the return value of the WC_Payment_Gateway_CC::generate_payment_request.
    		 *
    		 * @since 3.1.0
    		 * @param array $post_data
    		 * @param WC_Order $order
    		 * @param object $source
    		 */
    		return apply_filters( 'wc_stripe_generate_payment_request', $post_data, $order, $prepared_source );
    	}

    After that
    from woocommerce-gateway-stripe/abstracts/abstract-wc-stripe-payment-gateway.php

    I added this code:

    $get_selected_option = get_post_meta( $order_id, 'oow_selected_option', true);
    
        if ( $get_selected_option !== '' ) {
            $captured = 'no';
        }

    Modified Code:

    public function process_response( $response, $order ) {
    		WC_Stripe_Logger::log( 'Processing response: ' . print_r( $response, true ) );
    
    		$order_id = $order->get_id();
    		$captured = ( isset( $response->captured ) && $response->captured ) ? 'yes' : 'no';
    		
    		$get_selected_option = get_post_meta( $order_id, 'oow_selected_option', true);
                    // if the this conditions mecth should save as not captured $captured = 'no'
    		if ( $get_selected_option !== '' ) {
    			$captured = 'no';
    		}
    	
    		// Store charge data.
    		$order->update_meta_data( '_stripe_charge_captured', $captured );
    
    		if ( isset( $response->balance_transaction ) ) {
    			$this->update_fees( $order, is_string( $response->balance_transaction ) ? $response->balance_transaction : $response->balance_transaction->id );
    		}
    
    		if ( 'yes' === $captured ) {
    			/**
    			 * Charge can be captured but in a pending state. Payment methods
    			 * that are asynchronous may take couple days to clear. Webhook will
    			 * take care of the status changes.
    			 */
    			if ( 'pending' === $response->status ) {
    				$order_stock_reduced = $order->get_meta( '_order_stock_reduced', true );
    
    				if ( ! $order_stock_reduced ) {
    					wc_reduce_stock_levels( $order_id );
    				}
    
    				$order->set_transaction_id( $response->id );
    				/* translators: transaction id */
    				$order->update_status( 'on-hold', sprintf( __( 'Stripe charge awaiting payment: %s.', 'woocommerce-gateway-stripe' ), $response->id ) );
    			}
    
    			if ( 'succeeded' === $response->status ) {
    				$order->payment_complete( $response->id );
    
    				/* translators: transaction id */
    				$message = sprintf( __( 'Stripe charge complete (Charge ID: %s)', 'woocommerce-gateway-stripe' ), $response->id );
    				$order->add_order_note( $message );
    			}
    
    			if ( 'failed' === $response->status ) {
    				$localized_message = __( 'Payment processing failed. Please retry.', 'woocommerce-gateway-stripe' );
    				$order->add_order_note( $localized_message );
    				throw new WC_Stripe_Exception( print_r( $response, true ), $localized_message );
    			}
    		} else {
    			$order->set_transaction_id( $response->id );
    
    			if ( $order->has_status( [ 'pending', 'failed' ] ) ) {
    				wc_reduce_stock_levels( $order_id );
    			}
    
    			/* translators: transaction id */
    			$order->update_status( 'on-hold', sprintf( __( 'Stripe charge authorized (Charge ID: %s). Process order to take payment, or cancel to remove the pre-authorization. Attempting to refund the order in part or in full will release the authorization and cancel the payment.', 'woocommerce-gateway-stripe' ), $response->id ) );
    		}
    
    		if ( is_callable( [ $order, 'save' ] ) ) {
    			$order->save();
    		}
    
    		do_action( 'wc_gateway_stripe_process_response', $response, $order );
    
    		return $response;
    	}
Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Support AW a11n

    (@slash1andy)

    Automattic Happiness Engineer

    Hey there!

    This is a fairly complex development topic. I’m going to leave it open for a bit to see if anyone is able to chime in to help you out.

    I can also recommend the WooCommerce Developer Resources Portal for resources on developing for WooCommerce.

    You can also visit the WooCommerce Facebook group or the #developers channel of the WooCommerce Community Slack. We’re lucky to have a great community of open-source developers for WooCommerce, and many of our developers hang out there, as well.

    One other thing to consider would be to use/perhaps modify a plugin like WooCommerce Pre-Orders to do this, as it sounds similar.

    Thread Starter fagworio

    (@fagworio)

    Thanks, for your reply.

    Plugin Support AW a11n

    (@slash1andy)

    Automattic Happiness Engineer

    Since we haven’t had any other responses here, I’m going to mark this as resolved.

    If you have any further questions, you can start a new thread.

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Manual order, depending on the product I have in the order’ is closed to new replies.