Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Mollie Components #15

Closed
rvdsteege opened this issue Oct 27, 2022 · 5 comments · Fixed by #40
Closed

Add support for Mollie Components #15

rvdsteege opened this issue Oct 27, 2022 · 5 comments · Fixed by #40
Assignees

Comments

@rvdsteege
Copy link
Member

rvdsteege commented Oct 27, 2022

From customer:

With the Pronamic plugin, is it possible to display the Mollie payment module directly in the form (in the page of the form) created via Formidable Form?

Mollie presents this direct integration option as "Mollie Components", I wanted to know if this option is enabled by default.

@rvdsteege
Copy link
Member Author

@rvdsteege rvdsteege moved this to Todo in Pronamic Pay 9.2 Nov 30, 2022
@remcotolsma remcotolsma moved this from Todo to Deferred in Pronamic Pay 9.2 Dec 12, 2022
@rvdsteege
Copy link
Member Author

I checked the current status of this issue, but as it requires explicit integration with extensions (to first retrieve the token before submitting the checkout form) it might be better suited for a dedicated plugin integrating Mollie with WooCommerce?

For example, code like this is not at home in this repository:

  • function setupWooCommerce() {
    const checkoutForm = document.querySelector( 'form.woocommerce-checkout' );
    if ( ! checkoutForm ) {
    return;
    }
    // Init components on updated checkout.
    $( document.body ).on( 'updated_checkout', function( e ) {
    initMollieComponents( checkoutForm );
    } );
    const $form = $( checkoutForm );
    // Prevent placing order, need to create token first.
    $form.on( 'checkout_place_order_pronamic_pay_credit_card', returnFalse );
    // Re-enable placing order if card token has been added.
    checkoutForm.addEventListener( 'pronamic_pay_mollie_components_card_token_added', function( e ) {
    e.preventDefault();
    $form.off( 'checkout_place_order_pronamic_pay_credit_card', returnFalse );
    $form.submit();
    } );
    }

@remcotolsma
Copy link
Member

Discussed this today with @rvdsteege @pronamic HQ and we think this is a nice feature for Pronamic Pay 9.7. The specific WooCommerce code must be able to be edited out, for example by using input.form.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#instance_properties_related_to_the_parent_form

We can also introduce a credit card field in core so that this field does not have to be constructed via JavaScript. We then only have to mount the Mollie components to the subfields of our core credit card field.

@remcotolsma
Copy link
Member

It is more complex than expected, we have to look at the form handling per extension. For WooCommerce this can look like this:

var WooCommerceCheckout = {
	init: function() {
		jQuery( 'form.woocommerce-checkout' ).on( 'checkout_place_order', WooCommerceCheckout.checkout_place_order );
	},
	checkout_place_order: function() {
		var pronamicPayToken = PronamicPayToken( this );

		pronamicPayToken.then(
			function() {
				jQuery( 'form.woocommerce-checkout' ).off( 'checkout_place_order', WooCommerceCheckout.checkout_place_order );

				jQuery( 'form.woocommerce-checkout' ).submit();
			} 
		);

		return false;
	}
}

WooCommerceCheckout.init();

Per extension we need a way to halt the form submit, request the Mollie token, and resubmit the form. Should we use promises for this? We could use https://www.npmjs.com/package/@wordpress/hooks to allow extensions or gateways to hook in.

const pronamicPayTokenPromises = applyFilters( 'pronamicPayTokenPromises', [], this );

Promise.all( pronamicPayTokenPromises ).then(
	function() {
		// resubmit
	}
);
addFilter( 'pronamicPayTokenPromises', 'pronamic/wp-pronamic-pay-mollie', function( promises ) {
	promises.push( mollie.createToken() );
} );

Should we name it pronamicPayTokenPromises or more abstract pronamicPayBeforeSubmit?

@remcotolsma
Copy link
Member

@rvdsteege I have now created something that I am somewhat satisfied with. For now only with support for the legacy WooCommerce checkout form. PR is open for review: #40. We still need to add some styling and maybe improve error handling? Let's discuss @pronamic HQ tomorrow?

/* global Mollie */
/* eslint-env jquery */
/**
* Pronamic Pay Mollie WooCommerce legacy checkout form controller class
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_classes
*/
class PronamicPayMollieWooCommerceLegacyCheckoutFormController {
/**
* Construct Pronamic Pay Mollie WooCommerce lgeacy checkout form controller.
*
* @param {jQuery} jQuery The jQuery library.
* @param {HTMLElement} body Body element.
* @param {HTMLElement} form WooCommerce legacy checkout form element.
*/
constructor( jQuery, body, form ) {
this.jQuery = jQuery;
this.body = body;
this.form = form;
}
/**
* Setup.
*/
setup() {
this.jQuery( this.body ).on( 'init_checkout', () =>
this.initCheckout()
);
}
/**
* Init checkout.
*
* @see https://github.com/woocommerce/woocommerce/blob/8.3.0/plugins/woocommerce/client/legacy/js/frontend/checkout.js#L56-L59
*/
initCheckout() {
const cardElement = this.form.querySelector(
'.pronamic-pay-mollie-card-field'
);
if ( null === cardElement ) {
return;
}
const mollieProfileId = cardElement.dataset.mollieProfileId;
const mollieOptions = JSON.parse( cardElement.dataset.mollieOptions );
this.mollie = Mollie( mollieProfileId, mollieOptions );
this.checkoutPlaceOrderListener = () => this.checkoutPlaceOrder();
this.jQuery( this.form ).on(
'checkout_place_order',
this.checkoutPlaceOrderListener
);
this.jQuery( this.body ).on( 'updated_checkout', () =>
this.updatedCheckout()
);
this.mollieCardComponent = this.mollie.createComponent( 'card' );
}
/**
* Updated checkout.
*
* @see https://github.com/woocommerce/woocommerce/blob/8.3.0/plugins/woocommerce/client/legacy/js/frontend/checkout.js#L428-L429
*/
updatedCheckout() {
if ( this.cardElement ) {
this.mollieCardComponent.unmount();
}
this.cardElement = this.form.querySelector(
'.pronamic-pay-mollie-card-field'
);
if ( null === this.cardElement ) {
return;
}
this.mollieCardComponent.mount( this.cardElement );
}
/**
* Checkout place order.
*
* @see https://github.com/woocommerce/woocommerce/blob/8.3.0/plugins/woocommerce/client/legacy/js/frontend/checkout.js#L478-L480
*/
checkoutPlaceOrder() {
this.mollie
.createToken()
.then( ( result ) => this.processTokenResponse( result ) );
return false;
}
/**
* Process token response.
*
* @param {Object} result Mollie create token repsonse object.
*/
processTokenResponse( result ) {
if ( result.error ) {
return;
}
const tokenElement = document.getElementById(
'pronamic_pay_mollie_card_token'
);
if ( tokenElement ) {
tokenElement.value = result.token;
}
this.jQuery( this.form ).off(
'checkout_place_order',
this.checkoutPlaceOrderListener
);
this.jQuery( this.form ).submit();
}
}
/**
* Initialization.
*/
( function () {
if ( ! jQuery ) {
return;
}
if ( ! document.forms.checkout ) {
return;
}
const controller =
new PronamicPayMollieWooCommerceLegacyCheckoutFormController(
jQuery,
document.body,
document.forms.checkout
);
controller.setup();
} )();

@remcotolsma remcotolsma moved this from Todo to In Progress in Pronamic Pay Dec 5, 2023
@remcotolsma remcotolsma moved this from Todo to In Progress in Pronamic Pay 9.7 Dec 5, 2023
@remcotolsma remcotolsma linked a pull request Dec 5, 2023 that will close this issue
@github-project-automation github-project-automation bot moved this from In Progress to Done in Pronamic Pay Dec 6, 2023
@github-project-automation github-project-automation bot moved this from Deferred to Done in Pronamic Pay 9.2 Dec 6, 2023
@github-project-automation github-project-automation bot moved this from In Progress to Done in Pronamic Pay 9.7 Dec 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Status: Done
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants