PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260917
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260917
260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 120213 All 189 releases
s2member / src / includes / classes / sc-paypal-button-in.inc.php

sc-paypal-button-in.inc.php in s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions 260917, at src/includes/classes/sc-paypal-button-in.inc.php

983 lines 84.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // @codingStandardsIgnoreFile
3 /**
4 * Shortcode `[s2Member-PayPal-Button]` (inner processing routines).
5 *
6 * Copyright: © 2009-2011
7 * {@link http://websharks-inc.com/ WebSharks, Inc.}
8 * (coded in the USA)
9 *
10 * Released under the terms of the GNU General Public License.
11 * You should have received a copy of the GNU General Public License,
12 * along with this software. In the main directory, see: /licensing/
13 * If not, see: {@link http://www.gnu.org/licenses/}.
14 *
15 * @package s2Member\PayPal
16 * @since 3.5
17 */
18 if(!defined('WPINC')) // MUST have WordPress.
19 exit("Do not access this file directly.");
20
21 if (!class_exists ("c_ws_plugin__s2member_sc_paypal_button_in"))
22 {
23 /**
24 * Shortcode `[s2Member-PayPal-Button]` (inner processing routines).
25 *
26 * @package s2Member\PayPal
27 * @since 3.5
28 */
29 class c_ws_plugin__s2member_sc_paypal_button_in
30 {
31 /**
32 * Handles the Shortcode for: `[s2Member-PayPal-Button /]`.
33 *
34 * @package s2Member\PayPal
35 * @since 3.5
36 *
37 * @attaches-to ``add_shortcode("s2Member-PayPal-Button");``
38 *
39 * @param array $attr An array of Attributes.
40 * @param string $content Content inside the Shortcode.
41 * @param string $shortcode The actual Shortcode name itself.
42 * @return string The resulting PayPal Button Code.
43 */
44 public static function sc_paypal_button ($attr = FALSE, $content = FALSE, $shortcode = FALSE)
45 {
46 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
47 do_action("ws_plugin__s2member_before_sc_paypal_button", get_defined_vars ());
48 unset($__refs, $__v);
49
50 c_ws_plugin__s2member_no_cache::no_cache_constants /* No caching on pages that contain this Payment Button. */ (true);
51
52 $attr = /* Force array. Trim quote entities. */ c_ws_plugin__s2member_utils_strings::trim_qts_deep ((array)$attr);
53
54 $attr = shortcode_atts (apply_filters("ws_plugin__s2member_sc_paypal_button_default_attrs", array("ids" => "0", "exp" => "72", "level" => "1", "ccaps" => "", "desc" => "", "ps" => "paypal", "lc" => "", "lang" => "", "cc" => "USD", "dg" => "0", "ns" => "1", "custom" => $_SERVER["HTTP_HOST"], "ta" => "0", "tp" => "0", "tt" => "D", "ra" => "0.01", "rp" => "1", "rt" => "M", "rr" => "1", "rrt" => "", "rra" => "1", "modify" => "0", "cancel" => "0", "sp" => "0", "image" => "default", "output" => "button"), get_defined_vars ()), $attr);
55
56 // "modify" has been deprecated. https://developer.paypal.com/docs/classic/paypal-payments-standard/integration-guide/Appx-websitestandard-htmlvariables/#deprecated-variables
57 $attr["modify"] = "0";
58
59 $attr["lc"] = /* Locale code absolutely must be provided in upper-case format. Only after running shortcode_atts(). */ strtoupper ($attr["lc"]);
60 $attr["tt"] = /* Term lengths absolutely must be provided in upper-case format. Only after running shortcode_atts(). */ strtoupper ($attr["tt"]);
61 $attr["rt"] = /* Term lengths absolutely must be provided in upper-case format. Only after running shortcode_atts(). */ strtoupper ($attr["rt"]);
62 $attr["rr"] = /* Must be provided in upper-case format. Numerical, or BN value. Only after running shortcode_atts(). */ strtoupper ($attr["rr"]);
63 $attr["ccaps"] = /* Custom Capabilities must be typed in lower-case format. Only after running shortcode_atts(). */ strtolower ($attr["ccaps"]);
64 $attr["ccaps"] = /* Custom Capabilities should not have spaces. */ str_replace(" ", "", $attr["ccaps"]);
65 $attr["rr"] = /* Lifetime Subscriptions require Buy Now. Only after running shortcode_atts(). */ ($attr["rt"] === "L") ? "BN" : $attr["rr"];
66 $attr["rr"] = /* Independent Ccaps require Buy Now. Only after running shortcode_atts(). */ ($attr["level"] === "*") ? "BN" : $attr["rr"];
67 $attr["ns"] = /* No shipping directive must be 1 for digital items. After shortcode_atts(). */ ($attr["dg"] === "1") ? "1" : $attr["ns"];
68 $attr["ta"] = /*260228 Normalize trial amount to canonical 2-decimal currency format. */ number_format((float)$attr["ta"], 2, '.', '');
69 $attr["ra"] = /*260228 Normalize recurring/regular amount to canonical 2-decimal currency format. */ number_format((float)$attr["ra"], 2, '.', '');
70
71 //260811 Sanitize custom image URL.
72 if($attr["image"] !== "default")
73 $attr["image"] = esc_url_raw($attr["image"], array('http', 'https'));
74
75 $force_notify_url_scheme = apply_filters("ws_plugin__s2member_during_sc_paypal_button_force_notify_url_scheme", null, get_defined_vars ());
76 $force_return_url_scheme = apply_filters("ws_plugin__s2member_during_sc_paypal_button_force_return_url_scheme", null, get_defined_vars ());
77
78 // PayPal Checkout SDK memoization (per request; shared across all button variants).
79 static $ppco_sdks = array();
80
81 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
82 do_action("ws_plugin__s2member_before_sc_paypal_button_after_shortcode_atts", get_defined_vars ());
83 unset($__refs, $__v);
84
85 if /* Cancellation Buttons. */ ($attr["cancel"])
86 {
87 //260114 PayPal Checkout (REST) cancellation override.
88 // - output="button": on-site cancel via REST API (logged-in users only).
89 // - output="anchor|url": link to PayPal subscription management UI (sandbox/live aware).
90 // Falls back to legacy PayPal cancellation flow when user is not logged in or has no subscription id.
91 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled() && in_array($attr["output"], array("button", "anchor", "url"), true) && is_user_logged_in())
92 {
93 $user_id = (int)get_current_user_id();
94 $subscr_id = (string)get_user_option('s2member_subscr_id', $user_id);
95
96 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
97 $pp_manage_url = ($ppco_sandbox) ? 'https://www.sandbox.paypal.com/myaccount/autopay/connect/' : 'https://www.paypal.com/myaccount/autopay/'; //260218
98
99 // output="url|anchor": always link to PayPal subscription management UI.
100 if(in_array($attr["output"], array("url", "anchor"), true))
101 {
102 // output="url": return the PayPal management URL.
103 if($attr["output"] === "url")
104 {
105 $code = $_code = $pp_manage_url;
106
107 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
108 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
109 unset($__refs, $__v);
110
111 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
112 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
113 }
114 // output="anchor": real anchor tag to PayPal management UI (no JS).
115 else if($attr["output"] === "anchor")
116 {
117 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_unsubscribe_LG.gif";
118
119 if($attr["image"] && $attr["image"] !== "default")
120 {
121 $img_src = $attr["image"];
122 $code = $_code = '<a href="'.esc_attr($pp_manage_url).'" target="_blank" rel="nofollow noopener"><img src="'.esc_attr($img_src).'" style="width:auto; height:auto; border:0;" alt="PayPal" /></a>';
123 }
124 else
125 {
126 //260218 Match PayPal Checkout cancellation output="button" styling for output="anchor" (default image).
127 $ppco_cancel_label = esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member'));
128 $ppco_a_id = 's2member_ppco_cancel_anchor_'.md5($user_id.$subscr_id);
129
130 $code = '<style type="text/css">a#'.esc_attr($ppco_a_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 !important;color:#003087 !important;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:600;cursor:pointer;box-sizing:border-box;white-space:nowrap;text-decoration:none !important;} a#'.esc_attr($ppco_a_id).':link,a#'.esc_attr($ppco_a_id).':visited,a#'.esc_attr($ppco_a_id).':active{color:#003087 !important;background:#ffc439 !important;text-decoration:none !important;} a#'.esc_attr($ppco_a_id).':hover{color:#003087 !important;text-decoration:none !important;filter:brightness(0.98);}</style>'."\n";
131 $code .= '<a id="'.esc_attr($ppco_a_id).'" href="'.esc_attr($pp_manage_url).'" target="_blank" rel="nofollow noopener">'.$ppco_cancel_label.'</a>';
132 $_code = $code;
133 }
134
135 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
136 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
137 unset($__refs, $__v);
138
139 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
140 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
141 }
142 }
143
144 if($subscr_id)
145 {
146
147 // output="button": if Paid Subscr. ID is not a subscription id, fall back to PayPal management UI.
148 if($attr["output"] === "button" && !preg_match('/^I-[A-Z0-9]+$/', $subscr_id))
149 {
150 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_unsubscribe_LG.gif";
151
152 if($attr["image"] && $attr["image"] !== "default")
153 {
154 $img_src = $attr["image"];
155 $code = $_code = '<a href="'.esc_attr($pp_manage_url).'" target="_blank" rel="nofollow noopener"><img src="'.esc_attr($img_src).'" style="width:auto; height:auto; border:0;" alt="PayPal" /></a>';
156 }
157 else
158 {
159 //260218 Match PayPal Checkout cancellation output="button" styling for fallback output="anchor" (default image).
160 $ppco_cancel_label = esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member'));
161 $ppco_a_id = 's2member_ppco_cancel_anchor_'.md5($user_id.$subscr_id);
162
163 $code = '<style type="text/css">a#'.esc_attr($ppco_a_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 !important;color:#003087 !important;font-family:Helvetica, Arial, sans-serif;font-size:14px;font-weight:600;cursor:pointer;box-sizing:border-box;white-space:nowrap;text-decoration:none !important;} a#'.esc_attr($ppco_a_id).':link,a#'.esc_attr($ppco_a_id).':visited,a#'.esc_attr($ppco_a_id).':active{color:#003087 !important;background:#ffc439 !important;text-decoration:none !important;} a#'.esc_attr($ppco_a_id).':hover{color:#003087 !important;text-decoration:none !important;filter:brightness(0.98);}</style>'."\n";
164 $code .= '<a id="'.esc_attr($ppco_a_id).'" href="'.esc_attr($pp_manage_url).'" target="_blank" rel="nofollow noopener">'.$ppco_cancel_label.'</a>';
165 $_code = $code;
166 }
167
168 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
169 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
170 unset($__refs, $__v);
171
172 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
173 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
174 }
175
176 // output="button": REST cancel (modern-looking HTML button).
177 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
178
179 // Token must satisfy the standard token validator (invoice/ip/item_number/checksum).
180 $ppco_invoice = 'cancel-'.$user_id.'-'.$subscr_id;
181
182 $ppco_token = array(
183 'exp' => time() + 3600,
184 'invoice' => $ppco_invoice,
185 'ip' => c_ws_plugin__s2member_utils_ip::current(),
186 'item_number' => $subscr_id,
187 'checksum' => md5($ppco_invoice.c_ws_plugin__s2member_utils_ip::current().$subscr_id),
188
189 'user_id' => $user_id,
190 'subscr_id' => $subscr_id,
191 );
192
193 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
194 $ppco_nonce = wp_create_nonce('s2m_ppco_cancel_'.$user_id);
195
196 $ppco_btn_id = 's2member_ppco_cancel_'.md5($user_id.$subscr_id);
197 $ppco_msg_id = 's2member_ppco_cancel_msg_'.md5($user_id.$subscr_id);
198
199 //260913.1946 Validate Pro's optional success URL before exposing it to cancellation JavaScript; shortcode attributes may be authored by Editors.
200 $ppco_success_url = (c_ws_plugin__s2member_utils_conds::pro_is_installed() && !empty($attr["success"]) && is_string($attr["success"])) ? wp_validate_redirect($attr["success"], '') : '';
201 $ppco_success_json = wp_json_encode($ppco_success_url, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
202
203 $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";
204 $code .= '<button type="button" id="'.esc_attr($ppco_btn_id).'">'.esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member')).'</button>'."\n"; //260218
205 $code .= '<div id="'.esc_attr($ppco_msg_id).'" style="display:none; margin-top:8px;"></div>'."\n";
206 $code .= '<script type="text/javascript">'."\n";
207 $code .= '(function(){'."\n";
208 $code .= 'var b=document.getElementById("'.esc_js($ppco_btn_id).'");'."\n";
209 $code .= 'var m=document.getElementById("'.esc_js($ppco_msg_id).'");'."\n";
210 $code .= 'var u="'.esc_js($pp_manage_url).'";'."\n";
211 $code .= 'var s='.$ppco_success_json.';'."\n";
212 $code .= 'function goManage(){try{var w=window.open(u,"_blank","noopener");if(!w){window.location.href=u;}}catch(e){window.location.href=u;}}'."\n";
213 $code .= 'function show(msg){try{if(m){m.style.display="block";m.innerHTML=msg;}}catch(e){}}'."\n";
214 $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";
215 $code .= 'if(!b){return;}'."\n";
216 $code .= 'b.addEventListener("click",function(e){'."\n";
217 $code .= 'e.preventDefault();'."\n";
218 $code .= 'if(b.disabled){return;}'."\n";
219 $code .= 'if(!window.confirm("'.esc_js(__('Cancel your subscription now?', 's2member')).'")){return;}'."\n"; //260218
220 $code .= 'b.disabled=true;'."\n";
221 $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";
222 $code .= '.then(function(r){return r.json();})'."\n";
223 $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.
224 $code .= '.catch(function(){goManage(); b.disabled=false;});'."\n";
225 $code .= '});'."\n";
226 $code .= '})();'."\n";
227 $code .= '</script>'."\n";
228 $_code = $code;
229
230 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
231 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
232 unset($__refs, $__v);
233
234 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
235 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
236 }
237 }
238 else if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled() && $attr["output"] === "button")
239 {
240 //260505 Guest output="button": show a disabled PayPal-styled button (no action). Guest output="anchor|url" falls through to the PayPal management link.
241 $ppco_btn_id = 's2member_ppco_cancel_disabled_'.md5((string)microtime(true));
242 $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:not-allowed;box-sizing:border-box;opacity:0.55;white-space:nowrap;}</style>'."\n";
243 $code .= '<button type="button" id="'.esc_attr($ppco_btn_id).'" disabled="disabled">'.esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member')).'</button>'."\n"; //260218
244 $_code = $code;
245
246 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
247 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
248 unset($__refs, $__v);
249
250 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
251 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
252 }
253
254 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_unsubscribe_LG.gif";
255
256 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
257 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
258 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
259
260 $endpoint_host = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
261 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
262 $endpoint_host = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox() ? "www.sandbox.paypal.com" : "www.paypal.com";
263
264 $autopay_url = (strpos($endpoint_host, 'sandbox') !== false)
265 ? "https://www.sandbox.paypal.com/myaccount/autopay/connect/"
266 : "https://www.paypal.com/myaccount/autopay/"; //260218
267
268 $code = preg_replace ("/%%autopay_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($autopay_url)), $code);
269 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
270 $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
271
272 $code = $_code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["image"])) . '"', $code) : preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($default_image)) . '"', $code);
273
274 $code = ($attr["output"] === "anchor") ? /* Already in anchor format; `button` format is not used in Cancellations. */ $code : $code;
275 if ($attr["output"] === "url" && preg_match ('/ href\="(.*?)"/', $code, $m) && ($href = $m[1]))
276 $code = ($url = c_ws_plugin__s2member_utils_urls::n_amps ($href));
277
278 unset /* Just a little housekeeping */ ($href, $url, $m);
279
280 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
281 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
282 unset($__refs, $__v);
283 }
284 else if /* Specific Post/Page Buttons. */ ($attr["sp"])
285 {
286 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_xpressCheckout.gif";
287
288 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
289 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
290
291 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
292 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
293
294 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
295
296 $attr["sp_ids_exp"] = /* Combined "sp:ids:expiration hours". */ "sp:" . $attr["ids"] . ":" . $attr["exp"];
297
298 $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1", $force_return_url_scheme);
299 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
300
301 //260114 PayPal Checkout (REST) SP (Specific Post/Page) override.
302 // Uses server-side create + server-side capture, then posts into existing IPN + Return handlers.
303 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
304 {
305 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
306 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
307
308 $ppco_cc = strtoupper((string)$attr["cc"]);
309 $ppco_intent = 'capture';
310
311 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
312
313 $ppco_sdk_just_loaded = false;
314 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
315 {
316 $ppco_sdks[$ppco_sdk_key] = array(
317 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
318 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
319 );
320 $ppco_sdk_just_loaded = true;
321 }
322
323 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
324 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
325
326 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
327 $ppco_cancel = home_url("/");
328
329 $ppco_token = array(
330 'exp' => time() + 3600,
331
332 'invoice' => $paypal_invoice_input_value,
333 'ip' => c_ws_plugin__s2member_utils_ip::current(),
334 'item_name' => $attr["desc"],
335 'item_number' => $attr["sp_ids_exp"],
336 'custom' => $attr["custom"],
337
338 'amount' => $attr["ra"],
339 'cc' => $ppco_cc,
340 'ns' => $attr["ns"],
341
342 'rr' => 'BN',
343
344 'on0' => $paypal_on0_input_value,
345 'os0' => $paypal_os0_input_value,
346 'on1' => $paypal_on1_input_value,
347 'os1' => $paypal_os1_input_value,
348
349 'return' => $success_return_url,
350 'cancel' => $ppco_cancel,
351
352 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["sp_ids_exp"]),
353 );
354
355 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
356
357 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
358 if($attr["output"] === "anchor" || $attr["output"] === "url")
359 {
360 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
361
362 if($attr["output"] === "url")
363 $code = $_code = $ppco_redirect_url;
364
365 else // output="anchor"
366 {
367 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
368 $code = $_code = '<a class="ws-plugin--s2member-paypal-button ws-plugin--s2member-paypal-anchor" href="'.esc_attr($ppco_redirect_url).'"><img class="ws-plugin--s2member-paypal-button-img" src="'.esc_attr($img_src).'" style="width:auto; height:auto; border:0; margin:0;" alt="PayPal" /></a>';
369 }
370
371 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
372 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
373 unset($__refs, $__v);
374
375 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
376 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
377 }
378
379 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["sp_ids_exp"]);
380 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["sp_ids_exp"]);
381
382 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
383 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
384
385 if(!$ppco_locale && $ppco_lc)
386 {
387 $site_locale = (string)get_locale();
388 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
389 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
390 else
391 $ppco_locale = 'en_'.strtoupper($ppco_lc);
392 }
393
394 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
395 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
396
397 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
398 //260114 !!! SP is capture-only; conditional subscription path below is dead code (cleanup/refactor later).
399 if($ppco_intent === 'subscription')
400 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&vault=true&intent=subscription&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
401 else
402 $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;
403
404 $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";
405 $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
406
407 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
408
409 if($ppco_sdk_just_loaded)
410 {
411 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
412 }
413
414 $code .= '<script type="text/javascript">'."\n";
415 $code .= '(function(){'."\n";
416 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
417 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
418 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
419 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
420 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
421 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
422 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
423 //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
424 $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";
425 $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.
426 $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";
427 $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";
428 if($ppco_intent === 'subscription')
429 {
430 $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";
431 $code .= 'var planId=null;'."\n";
432 $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";
433 $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";
434 $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
435 $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";
436 $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";
437 }
438 else
439 {
440 $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";
441 $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";
442 $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
443 $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";
444 $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";
445 }
446 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
447 $code .= '})();'."\n";
448 $code .= '</script>'."\n";
449 $_code = $code;
450
451 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
452 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
453 unset($__refs, $__v);
454
455 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
456 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
457 }
458
459 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
460 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
461 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
462
463 $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
464 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
465 $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
466 $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
467 $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1", $force_notify_url_scheme))), $code);
468 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
469 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
470
471 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
472 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
473 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
474 $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["sp_ids_exp"])) . '"', $code);
475 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
476 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
477 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
478
479 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
480
481 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
482 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
483 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
484 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
485
486 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
487
488 $code = $_code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["image"])) . '"', $code) : preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($default_image)) . '"', $code);
489
490 $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal" /></a>' : $code;
491 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
492
493 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
494 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
495 unset($__refs, $__v);
496 }
497 else if /* Independent Custom Capabilities. */ ($attr["level"] === "*")
498 {
499 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_xpressCheckout.gif";
500
501 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
502 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
503
504 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
505 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
506
507 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
508
509 $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
510 $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
511
512 $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1", $force_return_url_scheme);
513 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
514
515
516 //260114 PayPal Checkout (REST) CCAPS (Independent Custom Capabilities) override.
517 // Uses server-side create + server-side capture, then posts into existing IPN + Return handlers.
518 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
519 {
520 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
521 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
522
523 $ppco_cc = strtoupper((string)$attr["cc"]);
524 $ppco_intent = 'capture';
525
526 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
527
528 $ppco_sdk_just_loaded = false;
529 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
530 {
531 $ppco_sdks[$ppco_sdk_key] = array(
532 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
533 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
534 );
535 $ppco_sdk_just_loaded = true;
536 }
537
538 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
539 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
540
541 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
542 $ppco_cancel = home_url("/");
543
544 $ppco_token = array(
545 'exp' => time() + 3600,
546
547 'invoice' => $paypal_invoice_input_value,
548 'ip' => c_ws_plugin__s2member_utils_ip::current(),
549 'item_name' => $attr["desc"],
550 'item_number' => $attr["level_ccaps_eotper"],
551 'custom' => $attr["custom"],
552
553 'amount' => $attr["ra"],
554 'cc' => $ppco_cc,
555 'ns' => $attr["ns"],
556
557 'rr' => 'BN',
558
559 'on0' => $paypal_on0_input_value,
560 'os0' => $paypal_os0_input_value,
561 'on1' => $paypal_on1_input_value,
562 'os1' => $paypal_os1_input_value,
563
564 'return' => $success_return_url,
565 'cancel' => $ppco_cancel,
566
567 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["level_ccaps_eotper"]),
568 );
569
570 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
571
572 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
573 if($attr["output"] === "anchor" || $attr["output"] === "url")
574 {
575 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
576
577 if($attr["output"] === "url")
578 $code = $_code = $ppco_redirect_url;
579
580 else // output="anchor"
581 {
582 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
583 $code = $_code = '<a class="ws-plugin--s2member-paypal-button ws-plugin--s2member-paypal-anchor" href="'.esc_attr($ppco_redirect_url).'"><img class="ws-plugin--s2member-paypal-button-img" src="'.esc_attr($img_src).'" style="width:auto; height:auto; border:0; margin:0;" alt="PayPal" /></a>';
584 }
585
586 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
587 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
588 unset($__refs, $__v);
589
590 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
591 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
592 }
593
594 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
595 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
596
597 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
598 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
599
600 if(!$ppco_locale && $ppco_lc)
601 {
602 $site_locale = (string)get_locale();
603 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
604 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
605 else
606 $ppco_locale = 'en_'.strtoupper($ppco_lc);
607 }
608
609 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
610 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
611
612 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
613 //260114 !!! Independent CCAPS is capture-only; conditional subscription path below is dead code (cleanup/refactor later).
614 if($ppco_intent === 'subscription')
615 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&vault=true&intent=subscription&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
616 else
617 $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;
618
619 $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";
620 $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
621
622 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
623
624 if($ppco_sdk_just_loaded)
625 {
626 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
627 }
628
629 $code .= '<script type="text/javascript">'."\n";
630 $code .= '(function(){'."\n";
631 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
632 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
633 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
634 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
635 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
636 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
637 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
638 //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
639 $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";
640 $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.
641 $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";
642 $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";
643 if($ppco_intent === 'subscription')
644 {
645 $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";
646 $code .= 'var planId=null;'."\n";
647 $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";
648 $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";
649 $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
650 $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";
651 $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";
652 }
653 else
654 {
655 $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";
656 $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";
657 $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
658 $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";
659 $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";
660 }
661 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
662 $code .= '})();'."\n";
663 $code .= '</script>'."\n";
664 $_code = $code;
665
666 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
667 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
668 unset($__refs, $__v);
669
670 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
671 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
672 }
673
674 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
675 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
676 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
677
678 $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
679 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
680 $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
681 $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
682 $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1", $force_notify_url_scheme))), $code);
683 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
684 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
685
686 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
687 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
688 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
689 $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level_ccaps_eotper"])) . '"', $code);
690 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
691 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
692 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
693
694 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
695
696 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
697 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
698 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
699 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
700
701 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
702
703 $code = $_code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["image"])) . '"', $code) : preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($default_image)) . '"', $code);
704
705 $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal" /></a>' : $code;
706 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
707
708 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
709 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
710 unset($__refs, $__v);
711 }
712 else // Otherwise, we'll process this Button normally, using Membership routines.
713 {
714 $default_image = "https://www.paypal.com/" . (($attr["lang"]) ? $attr["lang"] : _x ("en_US", "s2member-front paypal-button-lang-code", "s2member")) . "/i/btn/btn_xpressCheckout.gif";
715
716 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
717 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
718
719 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
720 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
721
722 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
723
724 $attr["desc"] = (!$attr["desc"]) ? $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $attr["level"] . "_label"] : $attr["desc"];
725
726 // PayPal Checkout: rr=0 with no trial/initial should behave like Buy Now (one-time),
727 // so s2Member’s standard Buy Now/EOT routines run (mirrors other gateways).
728 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled()
729 && (string)$attr["rr"] === '0'
730 && (float)$attr["ta"] <= 0
731 && (int)$attr["tp"] <= 0)
732 {
733 $attr["rr"] = 'BN';
734 }
735
736 $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
737 $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
738
739 $success_return_tra = array("ta" => $attr["ta"], "tp" => $attr["tp"], "tt" => $attr["tt"], "ra" => $attr["ra"], "rp" => $attr["rp"], "rt" => $attr["rt"], "rr" => $attr["rr"], "rrt" => $attr["rrt"], "rra" => $attr["rra"], "invoice" => $paypal_invoice_input_value, "checksum" => md5 ($paypal_invoice_input_value . c_ws_plugin__s2member_utils_ip::current() . $attr["level_ccaps_eotper"]));
740
741 $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered (see below). */ home_url ("/?s2member_paypal_return=1", $force_return_url_scheme);
742 $success_return_url = add_query_arg ("s2member_paypal_return_tra", urlencode (c_ws_plugin__s2member_utils_encryption::encrypt (serialize ($success_return_tra))), $success_return_url);
743 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
744
745 //260106 PayPal Checkout (REST) Buy Now (rr=BN) override.
746 // Uses server-side create + server-side capture/confirm, then posts into existing IPN + Return handlers.
747 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
748 {
749 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
750 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
751
752 $ppco_cc = strtoupper((string)$attr["cc"]);
753 $ppco_intent = ($attr["rr"] === "BN") ? 'capture' : 'subscription';
754
755 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
756
757 $ppco_sdk_just_loaded = false;
758 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
759 {
760 $ppco_sdks[$ppco_sdk_key] = array(
761 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
762 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
763 );
764 $ppco_sdk_just_loaded = true;
765 }
766
767 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
768 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
769
770 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
771 $ppco_cancel = home_url("/");
772
773 $ppco_token = array(
774 'exp' => time() + 3600,
775
776 'invoice' => $paypal_invoice_input_value,
777 'ip' => c_ws_plugin__s2member_utils_ip::current(),
778 'item_name' => $attr["desc"],
779 'item_number' => $attr["level_ccaps_eotper"],
780 'custom' => $attr["custom"],
781
782 'amount' => $attr["ra"],
783 'cc' => $ppco_cc,
784 'ns' => $attr["ns"],
785
786 'rr' => $attr["rr"],
787 'rp' => $attr["rp"],
788 'rt' => $attr["rt"],
789
790 'rrt' => $attr["rrt"],
791 'rra' => $attr["rra"],
792
793 'ta' => $attr["ta"],
794 'tp' => $attr["tp"],
795 'tt' => $attr["tt"],
796
797 'on0' => $paypal_on0_input_value,
798 'os0' => $paypal_os0_input_value,
799 'on1' => $paypal_on1_input_value,
800 'os1' => $paypal_os1_input_value,
801
802 'old__subscr_gateway' => get_user_option('s2member_subscr_gateway'),
803 'old__subscr_id' => get_user_option('s2member_subscr_id'),
804 'old__subscr_baid' => get_user_option('s2member_subscr_baid'),
805 'old__subscr_cid' => get_user_option('s2member_subscr_cid'),
806 'old__ipn_signup_vars' => c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(), //260408 Capture the old context before PayPal/webhook processing can update the member's current profile.
807
808 'return' => $success_return_url,
809 'cancel' => $ppco_cancel,
810
811 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["level_ccaps_eotper"]),
812 );
813
814 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
815
816 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
817 if($attr["output"] === "anchor" || $attr["output"] === "url")
818 {
819 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
820
821 if($attr["output"] === "url")
822 $code = $_code = $ppco_redirect_url;
823
824 else // output="anchor"
825 {
826 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
827 $code = $_code = '<a class="ws-plugin--s2member-paypal-button ws-plugin--s2member-paypal-anchor" href="'.esc_attr($ppco_redirect_url).'"><img class="ws-plugin--s2member-paypal-button-img" src="'.esc_attr($img_src).'" style="width:auto; height:auto; border:0; margin:0;" alt="PayPal" /></a>';
828 }
829
830 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
831 do_action("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
832 unset($__refs, $__v);
833
834 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
835 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
836 }
837
838 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
839 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
840
841 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
842 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
843
844 if(!$ppco_locale && $ppco_lc)
845 {
846 $site_locale = (string)get_locale();
847 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
848 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
849 else
850 $ppco_locale = 'en_'.strtoupper($ppco_lc);
851 }
852
853 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
854 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
855
856 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
857 if($ppco_intent === 'subscription')
858 $ppco_sdk_src = $ppco_sdk_src.'?client-id='.rawurlencode($ppco_client_id).'&currency='.rawurlencode($ppco_cc).'&vault=true&intent=subscription&disable-funding=card'.$ppco_buyer_country_q.$ppco_locale_q;
859 else
860 $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;
861
862 $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";
863 $code .= '<div id="'.esc_attr($ppco_err_id).'" class="ws-plugin--s2member-ppco-message" style="display:none; margin:0;"></div>'."\n";
864
865 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
866
867 if($ppco_sdk_just_loaded)
868 {
869 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
870 }
871
872 $code .= '<script type="text/javascript">'."\n";
873 $code .= '(function(){'."\n";
874 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
875 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
876 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
877 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
878 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
879 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
880 $code .= 'var cid="'.esc_js($paypal_invoice_input_value).'";'."\n";
881 //260819.0042 Keep standalone Checkout feedback consistent with Pro-Forms while distinguishing cancellation from errors.
882 $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";
883 $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.
884 $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";
885 $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";
886 if($ppco_intent === 'subscription')
887 {
888 $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";
889 $code .= 'var planId=null;'."\n";
890 $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";
891 $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";
892 $code .= 'function onCancel(){showInfo("Subscription cancelled.");}'."\n";
893 $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 $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";
895 }
896 else
897 {
898 $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";
899 $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";
900 $code .= 'function onCancel(){showInfo("Payment cancelled.");}'."\n";
901 $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";
902 $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";
903 }
904 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
905 $code .= '})();'."\n";
906 $code .= '</script>'."\n";
907 $_code = $code;
908
909 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
910 do_action("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
911 unset($__refs, $__v);
912
913 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
914 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
915 }
916
917 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
918 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
919 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
920
921 $code = preg_replace ("/%%endpoint%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com")), $code);
922 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
923 $code = preg_replace ("/%%paypal_merchant_id%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_merchant_id"])), $code);
924 $code = preg_replace ("/%%level_label%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $attr["level"] . "_label"])), $code);
925 $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code); // This brings them back to Front Page.
926 $code = preg_replace ("/%%notify_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/?s2member_paypal_notify=1", $force_notify_url_scheme))), $code);
927 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
928 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
929 $code = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level"])), $code);
930
931 $code = preg_replace ('/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/', " $1", $code);
932 $code = ($attr["rr"] === "BN") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick$3", $code) : $code;
933 $code = ($attr["rr"] === "BN") ? preg_replace ('/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
934 $code = ($attr["rr"] === "BN" || !$attr["tp"]) ? preg_replace ('/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
935 $code = ($attr["rr"] !== "BN") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick-subscriptions$3", $code) : $code;
936 $code = ($attr["rr"] !== "BN") ? preg_replace ('/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
937
938 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
939 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
940 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
941 $code = preg_replace ('/ name\="item_number" value\="(.*?)"/', ' name="item_number" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level_ccaps_eotper"])) . '"', $code);
942 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
943 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
944 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
945
946 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
947
948 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
949 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
950 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
951 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
952
953 $code = preg_replace ('/ name\="modify" value\="(.*?)"/', ' name="modify" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["modify"])) . '"', $code);
954
955 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
956
957 $code = preg_replace ('/ name\="src" value\="(.*?)"/', ' name="src" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rr"])) . '"', $code);
958 $code = preg_replace ('/ name\="srt" value\="(.*?)"/', ' name="srt" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rrt"])) . '"', $code);
959 $code = preg_replace ('/ name\="sra" value\="(.*?)"/', ' name="sra" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rra"])) . '"', $code);
960
961 $code = preg_replace ('/ name\="a1" value\="(.*?)"/', ' name="a1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ta"])) . '"', $code);
962 $code = preg_replace ('/ name\="p1" value\="(.*?)"/', ' name="p1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["tp"])) . '"', $code);
963 $code = preg_replace ('/ name\="t1" value\="(.*?)"/', ' name="t1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["tt"])) . '"', $code);
964 $code = preg_replace ('/ name\="a3" value\="(.*?)"/', ' name="a3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
965 $code = preg_replace ('/ name\="p3" value\="(.*?)"/', ' name="p3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rp"])) . '"', $code);
966 $code = preg_replace ('/ name\="t3" value\="(.*?)"/', ' name="t3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rt"])) . '"', $code);
967
968 $code = $_code = ($attr["image"] && $attr["image"] !== "default") ? preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["image"])) . '"', $code) : preg_replace ('/ src\="(.*?)"/', ' src="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($default_image)) . '"', $code);
969
970 $code = ($attr["output"] === "anchor") ? '<a href="' . esc_attr (c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code)) . '"><img src="' . esc_attr (($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image) . '" style="width:auto; height:auto; border:0;" alt="PayPal" /></a>' : $code;
971 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
972
973 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
974 ($attr["modify"]) ? do_action("ws_plugin__s2member_during_sc_paypal_modification_button", get_defined_vars ()) : do_action("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
975 unset($__refs, $__v);
976 }
977 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
978
979 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
980 }
981 }
982 }
983