Julie
Julie

Reputation: 11

Add a custom payment gateway with a form in Woocommerce

In Woocommerce, I would like to have a custom payment gateway, with a complete form. And that the answers to that form, are displayed in the validation page (I think it is the thank you page in english) AND in the back office, in the order.

I'm not good enough in PHP to create this, all on my own. But I learn to be better, trying to understand how code is working.

So I tried to found something close to my question And I found this excellent answer:
Add a custom payment gateway with additional radio buttons in Woocommerce

which answer for 90% to my question.

I found myself how to add other type of form's elements, like text, checkboxes...

      /**
     * Output the "payment type" radio buttons fields in checkout.
     */
    public function payment_fields(){
        if ( $description = $this->get_description() ) {
            echo wpautop( wptexturize( $description ) );
        }

        /**echo '<style>#transaction_type_field label.radio { display:inline-block; margin:0 .8em 0 .4em}</style>';**/

        $option_keys = array_keys($this->options);

        woocommerce_form_field( 'transaction_type-1', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Espèces', $this->domain),
        ), reset( $option_keys ) );

        woocommerce_form_field( 'transaction_type-2', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Tickets restaurants', $this->domain),
        ), reset( $option_keys ) );

        woocommerce_form_field( 'transaction_type-3', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Chèques vacances', $this->domain),
        ), reset( $option_keys ) );

        woocommerce_form_field( 'transaction_type-4', array(
            'type'          => 'radio',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Payment Information - Test', $this->domain),
            'options'       => $this->options,
        ), reset( $option_keys ) );


    }

But I don't understand how to "stock" the answers and displayed it. I tried with the first checkbox and I tried this :

       /**
     * Save the chosen payment type as order meta data.
     *
     * @param object $order
     * @param array $data
     */
    public function save_order_payment_type_meta_data( $order, $data ) {
        if ( $data['payment_method'] === $this->id && isset($_POST['transaction_type-1']) )
            $order->update_meta_data('_transaction_type', esc_attr($_POST['transaction_type-1']) );
    }

But it is not working. I think I missed something, perhaps around this, that I don't understand :

reset( $option_keys )

So if you have the solution ans explanations to my problem, or at least a clue, it will help me a lot.

Upvotes: 0

Views: 3269

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254388

Try the following replacement code functions (for multiple checkboxes):

    /**
     * Output the "payment type" fields in checkout.
     */
    public function payment_fields(){
        if ( $description = $this->get_description() ) {
            echo wpautop( wptexturize( $description ) );
        }

        woocommerce_form_field( 'transaction_type-1', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Espèces', $this->domain),
        ), '' );

        woocommerce_form_field( 'transaction_type-2', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Tickets restaurants', $this->domain),
        ), '' );

        woocommerce_form_field( 'transaction_type-3', array(
            'type'          => 'checkbox',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Chèques vacances', $this->domain),
        ), '' );

        $option_keys = array_keys($this->options);

        woocommerce_form_field( 'transaction_type-4', array(
            'type'          => 'radio',
            'class'         => array('transaction_type form-row-wide'),
            'label'         => __('Payment Information - Test', $this->domain),
            'options'       => $this->options,
        ), reset( $option_keys ) );
    }

    /**
     * Save the chosen payment type as order meta data.
     *
     * @param object $order
     * @param array $data
     */
    public function save_order_payment_type_meta_data( $order, $data ) {
        if ( $data['payment_method'] === $this->id ) {
            $meta_value = array(); // Initializing

            if ( isset($_POST['transaction_type-1']) ) {
                $meta_value[1] = __('Espèces', $this->domain);
            }

            if ( isset($_POST['transaction_type-2']) ) {
                $meta_value[2] = __('Tickets restaurants', $this->domain);
            }

            if ( isset($_POST['transaction_type-3']) ) {
                $meta_value[3] = __('Chèques vacances', $this->domain);
            }

            // Save transaction type (from fields 1 to 3) as an array
            if( sizeof($meta_value) > 0 ) {
                $order->update_meta_data('_transaction_type', $meta_value );
            }

            // Save transaction type test (from fields 4) as a string
            if ( isset($_POST['transaction_type-4']) ) {
                $order->update_meta_data('_transaction_type_test', esc_attr($_POST['transaction_type-4']) );
            }
        }
    }

    /**
     * Display the chosen payment type on order totals table
     *
     * @param array    $total_rows
     * @param WC_Order $order
     * @param bool     $tax_display
     * @return array
     */
    public function display_transaction_type_order_item_totals( $total_rows, $order, $tax_display ){
        if( is_a( $order, 'WC_Order' ) && $order->get_meta('_transaction_type') ) {
            $new_rows = []; // Initializing
            $options  = $this->options;

            // Loop through order total lines
            foreach( $total_rows as $total_key => $total_values ) {
                $new_rows[$total_key] = $total_values;
                if( $total_key === 'payment_method' ) {
                    // Get transaction type array
                    if( $meta_data = $order->get_meta('_transaction_type') ) {
                        $new_rows['payment_type'] = [
                            'label' => __("Transaction type", $this->domain) . ':',
                            'value' => implode(',', $meta_data),
                        ];
                    }
                }
            }

            $total_rows = $new_rows;
        }
        return $total_rows;
    }

It should better work…

Related thread: Add a custom payment gateway with additional radio buttons in Woocommerce

Upvotes: 2

Related Questions