woocommerce / woocommerce-blocks

(Deprecated) This plugin has been merged into woocommerce/woocommerce
https://wordpress.org/plugins/woo-gutenberg-products-block/
GNU General Public License v3.0
406 stars 218 forks source link

Pass payment gateway data to the checkout payload #8098

Closed webdados closed 1 year ago

webdados commented 1 year ago

I'm integrating an existing payment gateway to WooCommerce Blocks and I'm stuck on how to pass the value of an input field to the checkout payload.

I already have the input field on the payment method:

image

How can I pass the value of the field to the checkout payload so I can use it on my process_payment and validate_fields methods?

webdados commented 1 year ago

Basically, I want to populate payment_data to use in the legacy handling of payment processing, as stated here: https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md#processing-payment

My React skills are close to zero and I'm implementing the payment gateway block by following WooCommerce-included payment gateway blocks, like bacs for example.

So where on my js code can I populate payment_data with the data inserted by the customer on my input field? https://gist.github.com/webdados/b3b3de9082a162c7e59d974d3e41cc8a

mikejolley commented 1 year ago

Some react is required here, using this hook: https://github.com/woocommerce/woocommerce-blocks/blob/1785fa9af83589fde005550f772230b15d74a4b2/docs/internal-developers/block-client-apis/checkout/checkout-api.md#usepaymentmethodinterface

I've added a small example to this doc which should show how to pass data from the client to the server: https://github.com/woocommerce/woocommerce-blocks/pull/8325/files

You'd need to adapt this to pass the value from your field. If you're storing the field state in react (should be), this shouldn't be a complex process.

Hope that's enough information to get you unblocked.

webdados commented 1 year ago

Thanks @mikejolley

I'm trying to implement this, as per the example at https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/block-client-apis/checkout/checkout-api.md#passing-a-value-from-the-client-through-to-server-side-payment-processing and getting useEffect is not defined.

Any ideas?

Here's my code: `const Content = ( props ) => { / Data to send to the server - https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/block-client-apis/checkout/checkout-api.md#passing-a-value-from-the-client-through-to-server-side-payment-processing / const { eventRegistration, emitResponse } = props; const { onPaymentProcessing } = eventRegistration; useEffect( () => { const unsubscribe = onPaymentProcessing( async () => { // Here we can do any processing we need, and then emit a response. // For example, we might validate a custom field, or perform an AJAX request, and then emit a response indicating it is valid or not. const mbway_ifthen_for_woocommerce_phone = '12345'; //This will need to be the value of the input field - just for test now const customDataIsValid = !! mbway_ifthen_for_woocommerce_phone.length;

        if ( customDataIsValid ) {
            return {
                type: emitResponse.responseTypes.SUCCESS,
                meta: {
                    paymentMethodData: {
                        mbway_ifthen_for_woocommerce_phone,
                    },
                },
            };
        }

        return {
            type: emitResponse.responseTypes.ERROR,
            message: 'There was an error',
        };
    } );
    // Unsubscribes when this component is unmounted.
    return () => {
        unsubscribe();
    };
}, [
    emitResponse.responseTypes.ERROR,
    emitResponse.responseTypes.SUCCESS,
    onPaymentProcessing,
] );
/* Content */
var description = React.createElement( 'p', null, decodeEntities( settings.description || '' ) );
var phonenumberinput = React.createElement( 'input', {
    type:         'tel',
    name:         settings.id+'_phone',
    id:           settings.id+'_phone',
    placeholder:  '9xxxxxxxx',
    autoComplete: 'off',
    maxLength:    '9',
    required:     true
} );
var phonenumberlabel = React.createElement( 'label', {
    htmlFor: settings.id+'_phone'
}, decodeEntities( settings.phonenumbertext || '' ) );
var phonenumber = React.createElement( 'div', {
    className: 'wc-block-components-text-input is-active'
}, '', phonenumberinput, phonenumberlabel );
return React.createElement( 'div', null, description, phonenumber );

};`

webdados commented 1 year ago

Nevermind, I just had to import it from react.

mikejolley commented 1 year ago

You can import them from https://developer.wordpress.org/block-editor/reference-guides/packages/packages-element/

webdados commented 1 year ago

I hit another wall. How do I get the field value inside useEffect > onPaymentProcessing, to send that instead of '12345'?

I know this is a React question and not actually a WooCommerce Blocks usage question, but help a guy making a payment gateway blocks compatible :-D

Here's the current code: https://gist.github.com/webdados/e3e0f1bfcbfceafb460f2ed8654b3a2b

image

I'm able to set the value on mbwayPhoneNumber onChange of the input field, but I can't access it at line 31. For example, I tested accessing settings at line 32 and it works, because it was declared "globally". I tried to const [mbwayPhoneNumber, setMbwayPhoneNumber] = useState(''); at line 17 but I get "invalid hook call".

Actually, I would prefer to get it directly from the DOM, at the onPaymentProcessing instead of using onChange, but I couldn't find out how.

This is probably very simple :-/ sorry.

mikejolley commented 1 year ago

Tried adding mbwayPhoneNumber as one of the dependencies on the useEffect hook?

useEffect( () => {
    // ....
}, [ mbwayPhoneNumber ] );
webdados commented 1 year ago

Perfect. It's working. Thanks again. 💪