Skip to content

Commit 44fa266

Browse files
committed
Refactor ApplePay and GooglePay into separate gateway
Process payment is decoupled from CC
1 parent 1d263b1 commit 44fa266

11 files changed

+592
-173
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
(function( $ ) {
2+
'use strict';
3+
// Checkout form.
4+
$( document.body ).on(
5+
'updated_checkout',
6+
function(e, data) {
7+
wc_monei_form.update_apple_google_label();
8+
// Update cofidis_widget.total on every updated_checkout event.
9+
if ( 'object' === typeof( data ) && data.fragments && data.fragments[ 'monei_new_total' ] ) {
10+
wc_monei_form.total = data.fragments[ 'monei_new_total' ];
11+
}
12+
13+
if (wc_monei_form.is_apple_selected()) {
14+
wc_monei_form.init_apple_google_pay();
15+
}
16+
}
17+
);
18+
// On Pay for order form.
19+
$( 'form#order_review' ).on(
20+
'click',
21+
function() {
22+
if (wc_monei_form.is_apple_selected()) {
23+
wc_monei_form.init_apple_google_pay();
24+
}
25+
}
26+
);
27+
28+
var wc_monei_form = {
29+
$checkout_form: $( 'form.woocommerce-checkout' ),
30+
$add_payment_form: $( 'form#add_payment_method' ),
31+
$order_pay_form: $( 'form#order_review' ),
32+
$cardInput: null,
33+
$container: null,
34+
$payment_request_container: null,
35+
$errorContainer: null,
36+
$paymentForm: null,
37+
is_checkout: false,
38+
is_add_payment_method: false,
39+
is_order_pay: false,
40+
form: null,
41+
submitted: false,
42+
init_counter: 0,
43+
init_apple_counter: 0,
44+
total: wc_monei_apple_google_params.total,
45+
cardholderNameRegex: /^[A-Za-zÀ-ú- ]{5,50}$/,
46+
init: function() {
47+
// Checkout Page
48+
if ( this.$checkout_form.length ) {
49+
this.is_checkout = true;
50+
this.form = this.$checkout_form;
51+
}
52+
53+
// Add payment method Page
54+
if ( this.$add_payment_form.length ) {
55+
this.is_add_payment_method = true;
56+
this.form = this.$add_payment_form;
57+
}
58+
59+
// Pay for order ( change_payment_method for subscriptions)
60+
if ( this.$order_pay_form.length ) {
61+
if(wc_monei_form.is_apple_selected()) {
62+
wc_monei_form.init_apple_google_pay()
63+
}
64+
65+
this.is_order_pay = true;
66+
this.form = this.$order_pay_form;
67+
68+
$('input[name="payment_method"]').on('change', function() {
69+
// Check if the apple google pay method is selected
70+
if (wc_monei_form.is_apple_selected()) {
71+
wc_monei_form.init_apple_google_pay();
72+
}
73+
});
74+
}
75+
76+
if ( this.form ) {
77+
this.form.on( 'change', this.on_change );
78+
}
79+
},
80+
on_change: function() {
81+
// Triggers on payment method selection.
82+
$( "[name='payment_method']" ).on(
83+
'change',
84+
function() {
85+
wc_monei_form.on_payment_selected();
86+
}
87+
);
88+
// Triggers on saved card selection.
89+
$( "[name='wc-monei-payment-token']" ).on(
90+
'change',
91+
function() {
92+
wc_monei_form.on_payment_selected();
93+
}
94+
);
95+
},
96+
on_payment_selected() {
97+
if ( wc_monei_form.is_apple_selected()) {
98+
99+
wc_monei_form.init_apple_google_pay();
100+
console.log('after')
101+
if ( wc_monei_form.is_checkout ) {
102+
$("[name='woocommerce_checkout_place_order']").attr('data-monei', 'submit');
103+
}
104+
$('#place_order').prop('disabled', true);
105+
return false;
106+
} else {
107+
if ( wc_monei_form.is_checkout ) {
108+
$('#place_order').prop('disabled', false);
109+
$( "[name='woocommerce_checkout_place_order']" ).removeAttr( 'data-monei' );
110+
}
111+
}
112+
},
113+
is_apple_selected: function() {
114+
return $( '#payment_method_monei_apple_google' ).is( ':checked' );
115+
},
116+
init_apple_google_pay: function() {
117+
// If checkout is updated (and monei was initiated already), ex, selecting new shipping methods, checkout is re-render by the ajax call.
118+
// and we need to reset the counter in order to initiate again the monei component.
119+
if ( wc_monei_form.$payment_request_container && 0 === wc_monei_form.$payment_request_container.childElementCount ) {
120+
wc_monei_form.init_apple_counter = 0;
121+
}
122+
123+
// init monei just once, despite how many times this may be triggered.
124+
if ( 0 !== this.init_apple_counter ) {
125+
return;
126+
}
127+
128+
if ( wc_monei_form.is_checkout ) {
129+
$( "[name='woocommerce_checkout_place_order']" ).attr( 'data-monei', 'submit' );
130+
}
131+
132+
wc_monei_form.instantiate_payment_request();
133+
wc_monei_form.$payment_request_container = document.getElementById('payment-request-container')
134+
135+
// We already init the button.
136+
this.init_apple_counter++;
137+
138+
},
139+
instantiate_payment_request: function() {
140+
var paymentRequest = monei.PaymentRequest({
141+
accountId: wc_monei_apple_google_params.account_id,
142+
sessionId: wc_monei_apple_google_params.session_id,
143+
amount: parseInt( wc_monei_form.total ),
144+
currency: wc_monei_apple_google_params.currency,
145+
onSubmit(result) {
146+
wc_monei_form.apple_google_token_handler( result.token );
147+
},
148+
onError(error) {
149+
console.error(error);
150+
},
151+
});
152+
paymentRequest.render('#payment-request-container');
153+
window.paymentRequest = paymentRequest;
154+
},
155+
apple_google_token_handler: function (token ) {
156+
$('#place_order').prop('disabled', false);
157+
wc_monei_form.create_hidden_input( 'monei_payment_request_token', 'payment-request-form', token );
158+
// Once Token is created, submit form.
159+
wc_monei_form.form.submit();
160+
},
161+
create_hidden_input: function( id, form, token ) {
162+
var hiddenInput = document.createElement( 'input' );
163+
hiddenInput.setAttribute( 'type', 'hidden' );
164+
hiddenInput.setAttribute( 'name', id );
165+
hiddenInput.setAttribute( 'id', id );
166+
hiddenInput.setAttribute( 'value', token );
167+
wc_monei_form.$paymentForm = document.getElementById( form );
168+
wc_monei_form.$paymentForm.appendChild( hiddenInput );
169+
},
170+
/**
171+
* If Apple can make payments then we need to show the apple logo and title instead of Google
172+
*/
173+
update_apple_google_label: function () {
174+
const isApple = window.ApplePaySession?.canMakePayments();
175+
if (isApple) {
176+
const label = document.querySelector('label[for="payment_method_monei_apple_google"]');
177+
if (label) {
178+
label.childNodes[0].nodeValue = "Apple Pay ";
179+
const icon = label.querySelector('img');
180+
if (icon) {
181+
icon.src = wc_monei_apple_google_params.apple_logo;
182+
icon.alt = "Apple Pay";
183+
}
184+
}
185+
}
186+
}
187+
};
188+
189+
$(
190+
function() {
191+
wc_monei_form.init();
192+
wc_monei_form.update_apple_google_label();
193+
}
194+
);
195+
196+
})( jQuery );
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
( function () {
2+
const { registerPaymentMethod } = wc.wcBlocksRegistry;
3+
const { __ } = wp.i18n;
4+
const { useEffect } = wp.element;
5+
const moneiData = wc.wcSettings.getSetting( 'monei_apple_google_data' );
6+
7+
const MoneiAppleGoogleContent = ( props ) => {
8+
const { responseTypes } = props.emitResponse;
9+
const { onPaymentSetup } =
10+
props.eventRegistration;
11+
const { activePaymentMethod } = props;
12+
13+
let requestToken = null;
14+
useEffect( () => {
15+
const placeOrderButton = document.querySelector(
16+
'.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
17+
);
18+
if ( activePaymentMethod === 'monei_apple_google' ) {
19+
if ( placeOrderButton ) {
20+
//on hover over the button the text should not change color to white
21+
placeOrderButton.style.color = 'black';
22+
placeOrderButton.style.backgroundColor = '#ccc';
23+
placeOrderButton.disabled = true;
24+
}
25+
}
26+
return () => {
27+
if ( placeOrderButton ) {
28+
placeOrderButton.style.color = '';
29+
placeOrderButton.style.backgroundColor = '';
30+
placeOrderButton.disabled = false;
31+
}
32+
};
33+
}, [ activePaymentMethod ] );
34+
useEffect( () => {
35+
// We assume the MONEI SDK is already loaded via wp_enqueue_script on the backend.
36+
if ( typeof monei !== 'undefined' && monei.PaymentRequest ) {
37+
initMoneiCard();
38+
} else {
39+
console.error( 'MONEI SDK is not available' );
40+
}
41+
}, [] ); // Empty dependency array ensures this runs only once when the component mounts.
42+
43+
/**
44+
* Initialize MONEI card input and handle token creation.
45+
*/
46+
const initMoneiCard = () => {
47+
if ( window.paymentRequest ) {
48+
window.paymentRequest.close();
49+
}
50+
const paymentRequest = monei.PaymentRequest( {
51+
accountId: moneiData.accountId,
52+
sessionId: moneiData.sessionId,
53+
language: moneiData.language,
54+
amount: parseInt( moneiData.total * 100 ),
55+
currency: moneiData.currency,
56+
onSubmit( result ) {
57+
if ( result.token ) {
58+
requestToken = result.token;
59+
const placeOrderButton = document.querySelector(
60+
'.wc-block-components-button.wp-element-button.wc-block-components-checkout-place-order-button.wc-block-components-checkout-place-order-button'
61+
);
62+
if ( placeOrderButton ) {
63+
placeOrderButton.style.color = '';
64+
placeOrderButton.style.backgroundColor = '';
65+
placeOrderButton.disabled = false;
66+
placeOrderButton.click();
67+
} else {
68+
console.error( 'Place Order button not found.' );
69+
}
70+
}
71+
},
72+
onError( error ) {
73+
console.error( error );
74+
console.error( error );
75+
},
76+
} );
77+
78+
const container = document.getElementById(
79+
'payment-request-container'
80+
);
81+
paymentRequest.render( container );
82+
};
83+
84+
// Hook into the payment setup
85+
useEffect( () => {
86+
const unsubscribePaymentSetup = onPaymentSetup( () => {
87+
// If no token was created, fail
88+
if ( ! requestToken ) {
89+
return {
90+
type: 'error',
91+
message: moneiData.tokenErrorString
92+
};
93+
}
94+
return {
95+
type: responseTypes.SUCCESS,
96+
meta: {
97+
paymentMethodData: {
98+
monei_payment_request_token: requestToken,
99+
},
100+
},
101+
};
102+
} );
103+
104+
return () => {
105+
unsubscribePaymentSetup();
106+
};
107+
}, [ onPaymentSetup ] );
108+
109+
return (
110+
<fieldset className="monei-fieldset monei-payment-request-fieldset">
111+
<div
112+
id="payment-request-container"
113+
className="monei-payment-request-container"
114+
>
115+
{ /* Google Pay button will be inserted here */ }
116+
</div>
117+
<input
118+
type="hidden"
119+
id="monei_payment_token"
120+
name="monei_payment_token"
121+
value=""
122+
/>
123+
<div id="monei-card-error" className="monei-error" />
124+
</fieldset>
125+
);
126+
};
127+
const appleGoogleLabel = () => {
128+
console.log(moneiData)
129+
130+
const isApple = window.ApplePaySession?.canMakePayments();
131+
console.log('isApple', isApple)
132+
const appleEnabled = moneiData.logo_apple !== false;
133+
const googleEnabled = moneiData.logo_google !== false;
134+
let logo = googleEnabled? moneiData.logo_google : false;
135+
logo = isApple && appleEnabled ? moneiData.logo_apple : logo;
136+
const title = isApple && appleEnabled
137+
? 'Apple Pay'
138+
: 'Google Pay';
139+
const shouldShowLogo =
140+
( isApple && moneiData?.logo_apple ) ||
141+
( ! isApple && moneiData?.logo_google );
142+
return (
143+
<div className="monei-label-container">
144+
<span className="monei-text">{ title }</span>
145+
{ shouldShowLogo && (
146+
<div className="monei-logo">
147+
<img src={ logo } alt="" />
148+
</div>
149+
) }
150+
</div>
151+
);
152+
};
153+
154+
/**
155+
* MONEI Payment Method React Component
156+
*/
157+
const AppleGooglePaymentMethod = {
158+
name: 'monei_apple_google',
159+
paymentMethodId: 'monei_apple_google',
160+
label: <div> { appleGoogleLabel() } </div>,
161+
ariaLabel: __( 'Apple/Google Pay Payment Gateway', 'monei' ),
162+
content: <MoneiAppleGoogleContent />,
163+
edit: <div>{ __( 'MONEI Payment Form (Edit Mode)', 'monei' ) }</div>,
164+
canMakePayment: () => true,
165+
supports: { features: [ 'products' ] },
166+
};
167+
168+
registerPaymentMethod( AppleGooglePaymentMethod );
169+
} )();

assets/js/monei-block-checkout-cc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,5 +514,5 @@
514514
supports: { features: [ 'products' ] },
515515
};
516516
registerPaymentMethod( MoneiPaymentMethod );
517-
registerPaymentMethod( AppleGooglePaymentMethod );
517+
//registerPaymentMethod( AppleGooglePaymentMethod );
518518
} )();

0 commit comments

Comments
 (0)