Skip to content

Commit

Permalink
Rework onboarding rendering and JS code
Browse files Browse the repository at this point in the history
- Add `ppcp_onboarding` object and separate sandbox/production callbacks.
- Prevent errors when loading `onboarding.js` outside of the settings screen.
- Workaround PayPal’s partner.js shortcomings.
  • Loading branch information
jorgeatorres committed Feb 4, 2021
1 parent ef8fbf6 commit b887041
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 61 deletions.
152 changes: 119 additions & 33 deletions modules/ppcp-onboarding/assets/js/onboarding.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,104 @@
function onboardingCallback(authCode, sharedId) {
const sandboxSwitchElement = document.querySelector('#ppcp-sandbox_on');
fetch(
PayPalCommerceGatewayOnboarding.endpoint,
{
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(
{
authCode: authCode,
sharedId: sharedId,
nonce: PayPalCommerceGatewayOnboarding.nonce,
env: sandboxSwitchElement && sandboxSwitchElement.checked ? 'sandbox' : 'production'
// Onboarding.
const ppcp_onboarding = {
BUTTON_SELECTOR: '[data-paypal-onboard-button]',
PAYPAL_JS_ID: 'ppcp-onboarding-paypal-js',
_timeout: false,

init: function() {
document.addEventListener('DOMContentLoaded', this.reload);
},

reload: function() {
const buttons = document.querySelectorAll(ppcp_onboarding.BUTTON_SELECTOR);

if (0 === buttons.length) {
return;
}

// Add event listeners to buttons.
buttons.forEach(
(element) => {
if (element.hasAttribute('data-ppcp-button-initialized')) {
return;
}
)

element.addEventListener(
'click',
(e) => {
if (!element.hasAttribute('data-ppcp-button-initialized') || 'undefined' === typeof window.PAYPAL) {
e.preventDefault();
}
}
);
}
);

// Clear any previous PayPal scripts.
[ppcp_onboarding.PAYPAL_JS_ID, 'signup-js', 'biz-js'].forEach(
(scriptID) => {
const scriptTag = document.getElementById(scriptID);

if (scriptTag) {
scriptTag.parentNode.removeChild(scriptTag);
}

if ('undefined' !== typeof window.PAYPAL) {
delete window.PAYPAL;
}
}
);

// Load PayPal scripts.
const paypalScriptTag = document.createElement('script');
paypalScriptTag.id = ppcp_onboarding.PAYPAL_JS_ID;
paypalScriptTag.src = PayPalCommerceGatewayOnboarding.paypal_js_url;
document.body.append(paypalScriptTag);

if (ppcp_onboarding._timeout) {
clearTimeout(ppcp_onboarding._timeout);
}
);

ppcp_onboarding._timeout = setTimeout(
() => {
buttons.forEach((element) => { element.setAttribute('data-ppcp-button-initialized', 'true'); });

if ('undefined' !== window.PAYPAL.apps.Signup) {
window.PAYPAL.apps.Signup.render();
}
},
1000
);
},

loginSeller: function(env, authCode, sharedId) {
fetch(
PayPalCommerceGatewayOnboarding.endpoint,
{
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(
{
authCode: authCode,
sharedId: sharedId,
nonce: PayPalCommerceGatewayOnboarding.nonce,
env: env
}
)
}
);
},


};

function ppcp_onboarding_sandboxCallback(...args) {
return ppcp_onboarding.loginSeller('sandbox', ...args);
}

function ppcp_onboarding_productionCallback(...args) {
return ppcp_onboarding.loginSeller('production', ...args);
}

/**
Expand Down Expand Up @@ -174,21 +256,23 @@ const disconnect = (event) => {
);

// Prevent a possibly dirty form arising from this particular checkbox.
sandboxSwitchElement.addEventListener(
'click',
(event) => {
const value = event.target.checked;

toggleSandboxProduction( ! value );

event.preventDefault();
event.stopPropagation();
setTimeout( () => {
event.target.checked = value;
}, 1
);
}
);
if (sandboxSwitchElement) {
sandboxSwitchElement.addEventListener(
'click',
(event) => {
const value = event.target.checked;

toggleSandboxProduction( ! value );

event.preventDefault();
event.stopPropagation();
setTimeout( () => {
event.target.checked = value;
}, 1
);
}
);
}

// document.querySelectorAll('#mainform input[type="checkbox"]').forEach(
// (checkbox) => {
Expand All @@ -207,6 +291,8 @@ const disconnect = (event) => {
}
)
}
)
);

// Onboarding buttons.
ppcp_onboarding.init();
})();
10 changes: 4 additions & 6 deletions modules/ppcp-onboarding/src/Assets/class-onboardingassets.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function __construct(
LoginSellerEndpoint $login_seller_endpoint
) {

$this->module_url = $module_url;
$this->module_url = untrailingslashit( $module_url );
$this->state = $state;
$this->login_seller_endpoint = $login_seller_endpoint;
}
Expand All @@ -78,9 +78,6 @@ public function register(): bool {
1,
true
);
if ( ! $this->should_render_onboarding_script() ) {
return false;
}

$url = $this->module_url . '/assets/js/onboarding.js';
wp_register_script(
Expand All @@ -94,8 +91,9 @@ public function register(): bool {
'ppcp-onboarding',
'PayPalCommerceGatewayOnboarding',
array(
'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ),
'endpoint' => home_url( \WC_AJAX::get_endpoint( LoginSellerEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( $this->login_seller_endpoint::nonce() ),
'paypal_js_url' => 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
)
);

Expand Down
48 changes: 26 additions & 22 deletions modules/ppcp-onboarding/src/Render/class-onboardingrenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,34 +52,36 @@ public function __construct( Settings $settings, PartnerReferrals $production_pa
$this->sandbox_partner_referrals = $sandbox_partner_referrals;
}

/**
* Returns the action URL for the onboarding button/link.
*
* @param boolean $is_production Whether the production or sandbox button should be rendered.
* @return string URL.
*/
public function get_signup_link( bool $is_production ) {
$args = array(
'displayMode' => 'minibrowser',
);

$url = $is_production ? $this->production_partner_referrals->signup_link() : $this->sandbox_partner_referrals->signup_link();
$url = add_query_arg( $args, $url );

return $url;
}

/**
* Renders the "Connect to PayPal" button.
*
* @param bool $is_production Whether the production or sandbox button should be rendered.
*/
public function render( bool $is_production ) {
try {
$args = array(
'displayMode' => 'minibrowser',
$this->render_button(
$this->get_signup_link( $is_production ),
$is_production ? 'connect-to-production' : 'connect-to-sandbox',
$is_production ? __( 'Connect to PayPal', 'woocommerce-paypal-payments' ) : __( 'Connect to PayPal Sandbox', 'woocommerce-paypal-payments' ),
$is_production ? 'production' : 'sandbox'
);

$url = $is_production ? $this->production_partner_referrals->signup_link() : $this->sandbox_partner_referrals->signup_link();
$url = add_query_arg( $args, $url );
$id = $is_production ? 'connect-to-production' : 'connect-to-sandbox';
$label = $is_production ? __( 'Connect to PayPal', 'woocommerce-paypal-payments' ) : __( 'Connect to PayPal Sandbox', 'woocommerce-paypal-payments' );
$this->render_button(
$url,
$id,
$label
);

$script_url = 'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js'; ?>
<script>document.querySelectorAll('[data-paypal-onboard-complete=onboardingCallback]').forEach( (element) => { element.addEventListener('click', (e) => {if ('undefined' === typeof PAYPAL ) e.preventDefault(); }) });</script>
<script
id="paypal-js"
src="<?php echo esc_url( $script_url ); ?>"
></script>
<?php
} catch ( RuntimeException $exception ) {
esc_html_e(
'We could not properly connect to PayPal. Please reload the page to continue',
Expand All @@ -94,14 +96,16 @@ public function render( bool $is_production ) {
* @param string $url The url of the button.
* @param string $id The ID of the button.
* @param string $label The button text.
* @param string $env The environment ('production' or 'sandbox').
*/
private function render_button( string $url, string $id, string $label ) {
private function render_button( string $url, string $id, string $label, string $env ) {
?>
<a
target="_blank"
class="button-primary"
id="<?php echo esc_attr( $id ); ?>"
data-paypal-onboard-complete="onboardingCallback"
data-paypal-onboard-complete="ppcp_onboarding_<?php echo esc_attr( $env ); ?>Callback"
data-paypal-onboard-button="true"
href="<?php echo esc_url( $url ); ?>"
data-paypal-button="true"
>
Expand Down

0 comments on commit b887041

Please sign in to comment.