PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260927
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260927
260927 260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 All 190 releases
← All changes | src/includes/classes/sc-paypal-button-in.inc.php +28 -16 260814 → 260927 View file →
@@ -74,8 +74,12 @@
74 74
75 75 $force_notify_url_scheme = apply_filters("ws_plugin__s2member_during_sc_paypal_button_force_notify_url_scheme", null, get_defined_vars ());
76 76 $force_return_url_scheme = apply_filters("ws_plugin__s2member_during_sc_paypal_button_force_return_url_scheme", null, get_defined_vars ());
77 77
78 + //260918.2104 TO-DO PayPal Checkout cache hardening: do not embed the one-hour, visitor-specific transaction token in rendered page HTML.
79 + // Render a cache-safe encrypted checkout definition instead, then mint the short-lived invoice/IP/user-context transaction token server-side
80 + // when checkout actually starts (output="button", "anchor", or "url"), preserving validation, idempotency, subscription context, and return/cancel behavior.
81 +
78 82 // PayPal Checkout SDK memoization (per request; shared across all button variants).
79 83 static $ppco_sdks = array();
80 84
81 85 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
@@ -195,8 +199,12 @@
195 199
196 200 $ppco_btn_id = 's2member_ppco_cancel_'.md5($user_id.$subscr_id);
197 201 $ppco_msg_id = 's2member_ppco_cancel_msg_'.md5($user_id.$subscr_id);
198 202
203 + //260913.1946 Validate Pro's optional success URL before exposing it to cancellation JavaScript; shortcode attributes may be authored by Editors.
204 + $ppco_success_url = (c_ws_plugin__s2member_utils_conds::pro_is_installed() && !empty($attr["success"]) && is_string($attr["success"])) ? wp_validate_redirect($attr["success"], '') : '';
205 + $ppco_success_json = wp_json_encode($ppco_success_url, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
206 +
199 207 $code = '<style type="text/css">#'.esc_attr($ppco_btn_id).'{display:inline-flex;align-items:center;justify-content:center;width:150px;height:40px;padding:10px 0;border-radius:4px;border:1px solid rgba(0,0,0,0.06);background:#ffc439;color:#003087;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:600;cursor:pointer;box-sizing:border-box;white-space:nowrap;}#'.esc_attr($ppco_btn_id).':hover{filter:brightness(0.98);}#'.esc_attr($ppco_btn_id).':disabled{opacity:0.65;cursor:not-allowed;}</style>'."\n";
200 208 $code .= '<button type="button" id="'.esc_attr($ppco_btn_id).'">'.esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member')).'</button>'."\n"; //260218
201 209 $code .= '<div id="'.esc_attr($ppco_msg_id).'" style="display:none; margin-top:8px;"></div>'."\n";
202 210 $code .= '<script type="text/javascript">'."\n";
@@ -203,8 +211,9 @@
203 211 $code .= '(function(){'."\n";
204 212 $code .= 'var b=document.getElementById("'.esc_js($ppco_btn_id).'");'."\n";
205 213 $code .= 'var m=document.getElementById("'.esc_js($ppco_msg_id).'");'."\n";
206 214 $code .= 'var u="'.esc_js($pp_manage_url).'";'."\n";
215 + $code .= 'var s='.$ppco_success_json.';'."\n";
207 216 $code .= 'function goManage(){try{var w=window.open(u,"_blank","noopener");if(!w){window.location.href=u;}}catch(e){window.location.href=u;}}'."\n";
208 217 $code .= 'function show(msg){try{if(m){m.style.display="block";m.innerHTML=msg;}}catch(e){}}'."\n";
209 218 $code .= 'function enc(o){var s=[];for(var k in o){if(!o.hasOwnProperty(k))continue;s.push(encodeURIComponent(k)+"="+encodeURIComponent(o[k]));}return s.join("&");}'."\n";
210 219 $code .= 'if(!b){return;}'."\n";
@@ -214,9 +223,9 @@
214 223 $code .= 'if(!window.confirm("'.esc_js(__('Cancel your subscription now?', 's2member')).'")){return;}'."\n"; //260218
215 224 $code .= 'b.disabled=true;'."\n";
216 225 $code .= 'fetch("'.esc_js($ppco_endpoint).'",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"cancel_subscription",s2member_paypal_checkout_t:"'.esc_js($ppco_token).'",s2member_paypal_checkout_nonce:"'.esc_js($ppco_nonce).'"} )})'."\n";
217 226 $code .= '.then(function(r){return r.json();})'."\n";
218 - $code .= '.then(function(res){if(res&&res.ok){show("'.esc_js(__('Subscription cancelled.', 's2member')).'");}else{goManage(); b.disabled=false;}})'."\n"; //260218
227 + $code .= '.then(function(res){if(res&&res.ok){if(s){window.location.assign(s);}else{show("'.esc_js(__('Subscription cancelled.', 's2member')).'");}}else{goManage(); b.disabled=false;}})'."\n"; //260913.1946 Honor Pro's validated success URL after a confirmed on-site cancellation.
219 228 $code .= '.catch(function(){goManage(); b.disabled=false;});'."\n";
220 229 $code .= '});'."\n";
221 230 $code .= '})();'."\n";
222 231 $code .= '</script>'."\n";
@@ -396,9 +405,9 @@
396 405 else
397 406 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&intent=capture&commit=true&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
398 407
399 408 $code = '<div id="'.esc_attr($ppco_div_id).'" class="ws-plugin--s2member-paypal-button ws-plugin--s2member-ppco-button" style="max-width:145px; width:auto; margin:0;"></div>'."\n";
400 - $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-error" style="display:none; margin:0;"></div>'."\n";
409 + $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
401 410
402 411 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
403 412
404 413 if($ppco_sdk_just_loaded)
@@ -414,10 +423,11 @@
414 423 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
415 424 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
416 425 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
417 426 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
418 - $code .= 'function showErr(m){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML=m;}}catch(x){}}'."\n";
419 - $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n";
427 + //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
428 + $code .= 'function showMsg(m,t){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML="<span class=\"ws-plugin--s2member-ppco-"+(t==="info"?"info":"error")+"\">"+m+"</span>";}}catch(x){}}function showErr(m){showMsg(m,"error");}function showInfo(m){showMsg(m,"info");}'."\n";
429 + $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.acceptCharset="UTF-8";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n"; //260817 Keep signed PayPal Checkout returns in UTF-8.
420 430 $code .= 'function enc(o){var a=[];for(var k in o){if(!o.hasOwnProperty(k))continue;a.push(encodeURIComponent(k)+"="+encodeURIComponent(o[k]));}return a.join("&");}'."\n";
421 431 $code .= 'function loadSdk(cb){var P=window[ns];if(P&&P.Buttons){cb(P);return;}var id=ns+"_sdk",tag=document.getElementById(id),done=false;function finish(){if(done)return;done=true;cb(window[ns]&&window[ns].Buttons?window[ns]:null);}function ok(){finish();}function fail(){finish();}if(tag){if(window[ns]&&window[ns].Buttons){finish();return;}if(tag.getAttribute("src")!==s){tag.setAttribute("src",s);}if(tag.readyState==="complete"||tag.readyState==="loaded"){setTimeout(finish,0);return;}tag.addEventListener("load",ok);tag.addEventListener("error",fail);setTimeout(finish,3500);return;}tag=document.createElement("script");tag.id=id;tag.setAttribute("data-namespace",ns);tag.src=s;tag.async=true;tag.onload=ok;tag.onerror=fail;(document.head||document.body||document.documentElement).appendChild(tag);setTimeout(finish,3500);}'."\n";
422 432 if($ppco_intent === 'subscription')
423 433 {
@@ -424,9 +434,9 @@
424 434 $code .= 'function getPlanId(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"get_plan_id",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.plan_id)return res.plan_id;throw(res&&res.error?res.error:"plan_get_failed");});}'."\n";
425 435 $code .= 'var planId=null;'."\n";
426 436 $code .= 'function createSubscription(data,actions){if(planId)return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});return getPlanId().then(function(pid){planId=pid;return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});});}'."\n";
427 437 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"confirm_subscription",s2member_paypal_checkout_t:t,subscription_id:(data&&data.subscriptionID?data.subscriptionID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"subscription_confirm_failed");}).catch(function(e){showErr("Subscription could not be completed. Please try again.");});}'."\n";
428 - $code .= 'function onCancel(){showErr("Subscription cancelled.");}'."\n";
438 + $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
429 439 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
430 440 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createSubscription:createSubscription,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
431 441 }
432 442 else
@@ -432,9 +442,9 @@
432 442 else
433 443 {
434 444 $code .= 'function createOrder(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"create_order",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.order_id)return res.order_id;throw(res&&res.error?res.error:"order_create_failed");});}'."\n";
435 445 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"capture_order",s2member_paypal_checkout_t:t,order_id:(data&&data.orderID?data.orderID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"order_capture_failed");}).catch(function(e){showErr("Payment could not be completed. Please try again.");});}'."\n";
436 - $code .= 'function onCancel(){showErr("Payment cancelled.");}'."\n";
446 + $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
437 447 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
438 448 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createOrder:createOrder,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
439 449 }
440 450 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
@@ -610,9 +620,9 @@
610 620 else
611 621 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&intent=capture&commit=true&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
612 622
613 623 $code = '<div id="'.esc_attr($ppco_div_id).'" class="ws-plugin--s2member-paypal-button ws-plugin--s2member-ppco-button" style="max-width:145px; width:auto; margin:0;"></div>'."\n";
614 - $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-error" style="display:none; margin:0;"></div>'."\n";
624 + $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
615 625
616 626 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
617 627
618 628 if($ppco_sdk_just_loaded)
@@ -628,10 +638,11 @@
628 638 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
629 639 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
630 640 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
631 641 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
632 - $code .= 'function showErr(m){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML=m;}}catch(x){}}'."\n";
633 - $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n";
642 + //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
643 + $code .= 'function showMsg(m,t){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML="<span class=\"ws-plugin--s2member-ppco-"+(t==="info"?"info":"error")+"\">"+m+"</span>";}}catch(x){}}function showErr(m){showMsg(m,"error");}function showInfo(m){showMsg(m,"info");}'."\n";
644 + $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.acceptCharset="UTF-8";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n"; //260817 Keep signed PayPal Checkout returns in UTF-8.
634 645 $code .= 'function enc(o){var a=[];for(var k in o){if(!o.hasOwnProperty(k))continue;a.push(encodeURIComponent(k)+"="+encodeURIComponent(o[k]));}return a.join("&");}'."\n";
635 646 $code .= 'function loadSdk(cb){var P=window[ns];if(P&&P.Buttons){cb(P);return;}var id=ns+"_sdk",tag=document.getElementById(id),done=false;function finish(){if(done)return;done=true;cb(window[ns]&&window[ns].Buttons?window[ns]:null);}function ok(){finish();}function fail(){finish();}if(tag){if(window[ns]&&window[ns].Buttons){finish();return;}if(tag.getAttribute("src")!==s){tag.setAttribute("src",s);}if(tag.readyState==="complete"||tag.readyState==="loaded"){setTimeout(finish,0);return;}tag.addEventListener("load",ok);tag.addEventListener("error",fail);setTimeout(finish,3500);return;}tag=document.createElement("script");tag.id=id;tag.setAttribute("data-namespace",ns);tag.src=s;tag.async=true;tag.onload=ok;tag.onerror=fail;(document.head||document.body||document.documentElement).appendChild(tag);setTimeout(finish,3500);}'."\n";
636 647 if($ppco_intent === 'subscription')
637 648 {
@@ -638,9 +649,9 @@
638 649 $code .= 'function getPlanId(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"get_plan_id",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.plan_id)return res.plan_id;throw(res&&res.error?res.error:"plan_get_failed");});}'."\n";
639 650 $code .= 'var planId=null;'."\n";
640 651 $code .= 'function createSubscription(data,actions){if(planId)return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});return getPlanId().then(function(pid){planId=pid;return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});});}'."\n";
641 652 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"confirm_subscription",s2member_paypal_checkout_t:t,subscription_id:(data&&data.subscriptionID?data.subscriptionID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"subscription_confirm_failed");}).catch(function(e){showErr("Subscription could not be completed. Please try again.");});}'."\n";
642 - $code .= 'function onCancel(){showErr("Subscription cancelled.");}'."\n";
653 + $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
643 654 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
644 655 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createSubscription:createSubscription,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
645 656 }
646 657 else
@@ -646,9 +657,9 @@
646 657 else
647 658 {
648 659 $code .= 'function createOrder(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"create_order",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.order_id)return res.order_id;throw(res&&res.error?res.error:"order_create_failed");});}'."\n";
649 660 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"capture_order",s2member_paypal_checkout_t:t,order_id:(data&&data.orderID?data.orderID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"order_capture_failed");}).catch(function(e){showErr("Payment could not be completed. Please try again.");});}'."\n";
650 - $code .= 'function onCancel(){showErr("Payment cancelled.");}'."\n";
661 + $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
651 662 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
652 663 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createOrder:createOrder,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
653 664 }
654 665 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
@@ -852,9 +863,9 @@
852 863 else
853 864 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&intent=capture&commit=true&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
854 865
855 866 $code = '<div id="'.esc_attr($ppco_div_id).'" class="ws-plugin--s2member-paypal-button ws-plugin--s2member-ppco-button" style="max-width:145px; width:auto; margin:0;"></div>'."\n";
856 - $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-error" style="display:none; margin:0;"></div>'."\n";
867 + $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
857 868
858 869 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
859 870
860 871 if($ppco_sdk_just_loaded)
@@ -870,10 +881,11 @@
870 881 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
871 882 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
872 883 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
873 884 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
874 - $code .= 'function showErr(m){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML=m;}}catch(x){}}'."\n";
875 - $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n";
885 + //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
886 + $code .= 'function showMsg(m,t){try{var el=document.getElementById(e);if(el){el.style.display="block";el.innerHTML="<span class=\"ws-plugin--s2member-ppco-"+(t==="info"?"info":"error")+"\">"+m+"</span>";}}catch(x){}}function showErr(m){showMsg(m,"error");}function showInfo(m){showMsg(m,"info");}'."\n";
887 + $code .= 'function postTo(url, data){var f=document.createElement("form");f.method="post";f.acceptCharset="UTF-8";f.action=url;for(var k in data){if(!data.hasOwnProperty(k))continue;var i=document.createElement("input");i.type="hidden";i.name=k;i.value=data[k];f.appendChild(i);}document.body.appendChild(f);f.submit();}'."\n"; //260817 Keep signed PayPal Checkout returns in UTF-8.
876 888 $code .= 'function enc(o){var a=[];for(var k in o){if(!o.hasOwnProperty(k))continue;a.push(encodeURIComponent(k)+"="+encodeURIComponent(o[k]));}return a.join("&");}'."\n";
877 889 $code .= 'function loadSdk(cb){var P=window[ns];if(P&&P.Buttons){cb(P);return;}var id=ns+"_sdk",tag=document.getElementById(id),done=false;function finish(){if(done)return;done=true;cb(window[ns]&&window[ns].Buttons?window[ns]:null);}function ok(){finish();}function fail(){finish();}if(tag){if(window[ns]&&window[ns].Buttons){finish();return;}if(tag.getAttribute("src")!==s){tag.setAttribute("src",s);}if(tag.readyState==="complete"||tag.readyState==="loaded"){setTimeout(finish,0);return;}tag.addEventListener("load",ok);tag.addEventListener("error",fail);setTimeout(finish,3500);return;}tag=document.createElement("script");tag.id=id;tag.setAttribute("data-namespace",ns);tag.src=s;tag.async=true;tag.onload=ok;tag.onerror=fail;(document.head||document.body||document.documentElement).appendChild(tag);setTimeout(finish,3500);}'."\n";
878 890 if($ppco_intent === 'subscription')
879 891 {
@@ -880,9 +892,9 @@
880 892 $code .= 'function getPlanId(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"get_plan_id",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.plan_id)return res.plan_id;throw(res&&res.error?res.error:"plan_get_failed");});}'."\n";
881 893 $code .= 'var planId=null;'."\n";
882 894 $code .= 'function createSubscription(data,actions){if(planId)return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});return getPlanId().then(function(pid){planId=pid;return actions.subscription.create({plan_id:planId,custom_id:cid,application_context:{shipping_preference:"NO_SHIPPING"}});});}'."\n";
883 895 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"confirm_subscription",s2member_paypal_checkout_t:t,subscription_id:(data&&data.subscriptionID?data.subscriptionID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"subscription_confirm_failed");}).catch(function(e){showErr("Subscription could not be completed. Please try again.");});}'."\n";
884 - $code .= 'function onCancel(){showErr("Subscription cancelled.");}'."\n";
896 + $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
885 897 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
886 898 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createSubscription:createSubscription,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
887 899 }
888 900 else
@@ -888,9 +900,9 @@
888 900 else
889 901 {
890 902 $code .= 'function createOrder(){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"create_order",s2member_paypal_checkout_t:t})}).then(function(r){return r.json();}).then(function(res){if(res&&res.order_id)return res.order_id;throw(res&&res.error?res.error:"order_create_failed");});}'."\n";
891 903 $code .= 'function onApprove(data){return fetch(u,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},body:enc({s2member_paypal_checkout_op:"capture_order",s2member_paypal_checkout_t:t,order_id:(data&&data.orderID?data.orderID:"")})}).then(function(r){return r.json();}).then(function(res){if(res&&res.rtn_url&&res.rtn_post){postTo(res.rtn_url,res.rtn_post);return;}throw(res&&res.error?res.error:"order_capture_failed");}).catch(function(e){showErr("Payment could not be completed. Please try again.");});}'."\n";
892 - $code .= 'function onCancel(){showErr("Payment cancelled.");}'."\n";
904 + $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
893 905 $code .= 'function onError(err){var m="PayPal error. Please try again.";try{if(err){if(typeof err==="string")m="PayPal error: "+err;else if(err.message)m="PayPal error: "+err.message;}}catch(x){}showErr(m);}'."\n";
894 906 $code .= 'function init(){loadSdk(function(P){var el=document.getElementById(d);if(!el){return;}if(el.getAttribute("data-s2m-ppco-rendered")==="1"){return;}if(!P||!P.Buttons){showErr("PayPal SDK failed to load.");return;}el.setAttribute("data-s2m-ppco-rendered","1");try{P.Buttons({fundingSource:P.FUNDING.PAYPAL,style:{layout:"vertical",tagline:false,height:40},createOrder:createOrder,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
895 907 }
896 908 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";