PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260814
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260814
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 260814, at src/includes/classes/sc-paypal-button-in.inc.php

975 lines 82.8 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 $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 $code .= '<button type="button" id="'.esc_attr($ppco_btn_id).'">'.esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member')).'</button>'."\n"; //260218
201 $code .= '<div id="'.esc_attr($ppco_msg_id).'" style="display:none; margin-top:8px;"></div>'."\n";
202 $code .= '<script type="text/javascript">'."\n";
203 $code .= '(function(){'."\n";
204 $code .= 'var b=document.getElementById("'.esc_js($ppco_btn_id).'");'."\n";
205 $code .= 'var m=document.getElementById("'.esc_js($ppco_msg_id).'");'."\n";
206 $code .= 'var u="'.esc_js($pp_manage_url).'";'."\n";
207 $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 $code .= 'function show(msg){try{if(m){m.style.display="block";m.innerHTML=msg;}}catch(e){}}'."\n";
209 $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 $code .= 'if(!b){return;}'."\n";
211 $code .= 'b.addEventListener("click",function(e){'."\n";
212 $code .= 'e.preventDefault();'."\n";
213 $code .= 'if(b.disabled){return;}'."\n";
214 $code .= 'if(!window.confirm("'.esc_js(__('Cancel your subscription now?', 's2member')).'")){return;}'."\n"; //260218
215 $code .= 'b.disabled=true;'."\n";
216 $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 $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
219 $code .= '.catch(function(){goManage(); b.disabled=false;});'."\n";
220 $code .= '});'."\n";
221 $code .= '})();'."\n";
222 $code .= '</script>'."\n";
223 $_code = $code;
224
225 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
226 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
227 unset($__refs, $__v);
228
229 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
230 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
231 }
232 }
233 else if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled() && $attr["output"] === "button")
234 {
235 //260505 Guest output="button": show a disabled PayPal-styled button (no action). Guest output="anchor|url" falls through to the PayPal management link.
236 $ppco_btn_id = 's2member_ppco_cancel_disabled_'.md5((string)microtime(true));
237 $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";
238 $code .= '<button type="button" id="'.esc_attr($ppco_btn_id).'" disabled="disabled">'.esc_html(_x('Unsubscribe', 'paypal cancellation button label', 's2member')).'</button>'."\n"; //260218
239 $_code = $code;
240
241 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
242 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
243 unset($__refs, $__v);
244
245 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
246 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
247 }
248
249 $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";
250
251 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-cancellation-button.php")));
252 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
253 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
254
255 $endpoint_host = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
256 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
257 $endpoint_host = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox() ? "www.sandbox.paypal.com" : "www.paypal.com";
258
259 $autopay_url = (strpos($endpoint_host, 'sandbox') !== false)
260 ? "https://www.sandbox.paypal.com/myaccount/autopay/connect/"
261 : "https://www.paypal.com/myaccount/autopay/"; //260218
262
263 $code = preg_replace ("/%%autopay_url%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($autopay_url)), $code);
264 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
265 $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);
266
267 $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);
268
269 $code = ($attr["output"] === "anchor") ? /* Already in anchor format; `button` format is not used in Cancellations. */ $code : $code;
270 if ($attr["output"] === "url" && preg_match ('/ href\="(.*?)"/', $code, $m) && ($href = $m[1]))
271 $code = ($url = c_ws_plugin__s2member_utils_urls::n_amps ($href));
272
273 unset /* Just a little housekeeping */ ($href, $url, $m);
274
275 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
276 do_action("ws_plugin__s2member_during_sc_paypal_cancellation_button", get_defined_vars ());
277 unset($__refs, $__v);
278 }
279 else if /* Specific Post/Page Buttons. */ ($attr["sp"])
280 {
281 $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";
282
283 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
284 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
285
286 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
287 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
288
289 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
290
291 $attr["sp_ids_exp"] = /* Combined "sp:ids:expiration hours". */ "sp:" . $attr["ids"] . ":" . $attr["exp"];
292
293 $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1", $force_return_url_scheme);
294 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
295
296 //260114 PayPal Checkout (REST) SP (Specific Post/Page) override.
297 // Uses server-side create + server-side capture, then posts into existing IPN + Return handlers.
298 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
299 {
300 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
301 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
302
303 $ppco_cc = strtoupper((string)$attr["cc"]);
304 $ppco_intent = 'capture';
305
306 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
307
308 $ppco_sdk_just_loaded = false;
309 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
310 {
311 $ppco_sdks[$ppco_sdk_key] = array(
312 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
313 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
314 );
315 $ppco_sdk_just_loaded = true;
316 }
317
318 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
319 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
320
321 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
322 $ppco_cancel = home_url("/");
323
324 $ppco_token = array(
325 'exp' => time() + 3600,
326
327 'invoice' => $paypal_invoice_input_value,
328 'ip' => c_ws_plugin__s2member_utils_ip::current(),
329 'item_name' => $attr["desc"],
330 'item_number' => $attr["sp_ids_exp"],
331 'custom' => $attr["custom"],
332
333 'amount' => $attr["ra"],
334 'cc' => $ppco_cc,
335 'ns' => $attr["ns"],
336
337 'rr' => 'BN',
338
339 'on0' => $paypal_on0_input_value,
340 'os0' => $paypal_os0_input_value,
341 'on1' => $paypal_on1_input_value,
342 'os1' => $paypal_os1_input_value,
343
344 'return' => $success_return_url,
345 'cancel' => $ppco_cancel,
346
347 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["sp_ids_exp"]),
348 );
349
350 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
351
352 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
353 if($attr["output"] === "anchor" || $attr["output"] === "url")
354 {
355 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
356
357 if($attr["output"] === "url")
358 $code = $_code = $ppco_redirect_url;
359
360 else // output="anchor"
361 {
362 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
363 $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>';
364 }
365
366 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
367 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
368 unset($__refs, $__v);
369
370 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
371 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
372 }
373
374 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["sp_ids_exp"]);
375 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["sp_ids_exp"]);
376
377 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
378 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
379
380 if(!$ppco_locale && $ppco_lc)
381 {
382 $site_locale = (string)get_locale();
383 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
384 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
385 else
386 $ppco_locale = 'en_'.strtoupper($ppco_lc);
387 }
388
389 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
390 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
391
392 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
393 //260114 !!! SP is capture-only; conditional subscription path below is dead code (cleanup/refactor later).
394 if($ppco_intent === 'subscription')
395 $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;
396 else
397 $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
399 $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";
401
402 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
403
404 if($ppco_sdk_just_loaded)
405 {
406 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
407 }
408
409 $code .= '<script type="text/javascript">'."\n";
410 $code .= '(function(){'."\n";
411 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
412 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
413 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
414 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
415 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
416 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
417 $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";
420 $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 $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 if($ppco_intent === 'subscription')
423 {
424 $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 $code .= 'var planId=null;'."\n";
426 $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 $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";
429 $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 $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 }
432 else
433 {
434 $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 $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";
437 $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 $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 }
440 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
441 $code .= '})();'."\n";
442 $code .= '</script>'."\n";
443 $_code = $code;
444
445 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
446 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
447 unset($__refs, $__v);
448
449 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
450 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
451 }
452
453 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-sp-checkout-button.php")));
454 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
455 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
456
457 $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);
458 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
459 $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);
460 $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
461 $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);
462 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
463 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
464
465 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
466 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
467 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
468 $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);
469 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
470 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
471 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
472
473 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
474
475 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
476 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
477 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
478 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
479
480 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
481
482 $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);
483
484 $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;
485 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
486
487 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
488 do_action("ws_plugin__s2member_during_sc_paypal_sp_button", get_defined_vars ());
489 unset($__refs, $__v);
490 }
491 else if /* Independent Custom Capabilities. */ ($attr["level"] === "*")
492 {
493 $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";
494
495 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
496 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
497
498 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
499 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
500
501 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
502
503 $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
504 $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
505
506 $success_return_url = /* s2Member handles this all by itself. However, it can be Filtered. */ home_url ("/?s2member_paypal_return=1", $force_return_url_scheme);
507 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
508
509
510 //260114 PayPal Checkout (REST) CCAPS (Independent Custom Capabilities) override.
511 // Uses server-side create + server-side capture, then posts into existing IPN + Return handlers.
512 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
513 {
514 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
515 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
516
517 $ppco_cc = strtoupper((string)$attr["cc"]);
518 $ppco_intent = 'capture';
519
520 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
521
522 $ppco_sdk_just_loaded = false;
523 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
524 {
525 $ppco_sdks[$ppco_sdk_key] = array(
526 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
527 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
528 );
529 $ppco_sdk_just_loaded = true;
530 }
531
532 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
533 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
534
535 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
536 $ppco_cancel = home_url("/");
537
538 $ppco_token = array(
539 'exp' => time() + 3600,
540
541 'invoice' => $paypal_invoice_input_value,
542 'ip' => c_ws_plugin__s2member_utils_ip::current(),
543 'item_name' => $attr["desc"],
544 'item_number' => $attr["level_ccaps_eotper"],
545 'custom' => $attr["custom"],
546
547 'amount' => $attr["ra"],
548 'cc' => $ppco_cc,
549 'ns' => $attr["ns"],
550
551 'rr' => 'BN',
552
553 'on0' => $paypal_on0_input_value,
554 'os0' => $paypal_os0_input_value,
555 'on1' => $paypal_on1_input_value,
556 'os1' => $paypal_os1_input_value,
557
558 'return' => $success_return_url,
559 'cancel' => $ppco_cancel,
560
561 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["level_ccaps_eotper"]),
562 );
563
564 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
565
566 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
567 if($attr["output"] === "anchor" || $attr["output"] === "url")
568 {
569 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
570
571 if($attr["output"] === "url")
572 $code = $_code = $ppco_redirect_url;
573
574 else // output="anchor"
575 {
576 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
577 $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>';
578 }
579
580 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
581 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
582 unset($__refs, $__v);
583
584 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
585 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
586 }
587
588 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
589 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
590
591 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
592 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
593
594 if(!$ppco_locale && $ppco_lc)
595 {
596 $site_locale = (string)get_locale();
597 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
598 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
599 else
600 $ppco_locale = 'en_'.strtoupper($ppco_lc);
601 }
602
603 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
604 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
605
606 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
607 //260114 !!! Independent CCAPS is capture-only; conditional subscription path below is dead code (cleanup/refactor later).
608 if($ppco_intent === 'subscription')
609 $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;
610 else
611 $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
613 $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";
615
616 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
617
618 if($ppco_sdk_just_loaded)
619 {
620 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
621 }
622
623 $code .= '<script type="text/javascript">'."\n";
624 $code .= '(function(){'."\n";
625 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
626 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
627 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
628 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
629 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
630 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
631 $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";
634 $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 $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 if($ppco_intent === 'subscription')
637 {
638 $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 $code .= 'var planId=null;'."\n";
640 $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 $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";
643 $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 $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 }
646 else
647 {
648 $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 $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";
651 $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 $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 }
654 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
655 $code .= '})();'."\n";
656 $code .= '</script>'."\n";
657 $_code = $code;
658
659 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
660 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
661 unset($__refs, $__v);
662
663 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
664 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
665 }
666
667 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-ccaps-checkout-button.php")));
668 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
669 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
670
671 $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);
672 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
673 $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);
674 $code = preg_replace ("/%%cancel_return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ("/"))), $code);
675 $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);
676 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
677 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
678
679 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
680 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
681 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
682 $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);
683 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
684 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
685 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
686
687 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
688
689 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
690 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
691 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
692 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
693
694 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
695
696 $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);
697
698 $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;
699 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
700
701 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
702 do_action("ws_plugin__s2member_during_sc_paypal_ccaps_button", get_defined_vars ());
703 unset($__refs, $__v);
704 }
705 else // Otherwise, we'll process this Button normally, using Membership routines.
706 {
707 $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";
708
709 $paypal_on0_input_value = ($referencing = c_ws_plugin__s2member_utils_users::get_user_subscr_or_wp_id ()) ? "Referencing Customer ID" : "Originating Domain";
710 $paypal_os0_input_value = /* Current User's Paid Subscr. ID, or WP User ID, or domain. */ ($referencing) ? $referencing : $_SERVER["HTTP_HOST"];
711
712 $paypal_on1_input_value = /* Identifies the Customer's IP Address for tracking purposes. */ "Customer IP Address";
713 $paypal_os1_input_value = /* Current User's IP Address for tracking purposes. */ c_ws_plugin__s2member_utils_ip::current();
714
715 $paypal_invoice_input_value = /* s2Member's Unique Code~IP combo. */ uniqid () . "~" . c_ws_plugin__s2member_utils_ip::current();
716
717 $attr["desc"] = (!$attr["desc"]) ? $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["level" . $attr["level"] . "_label"] : $attr["desc"];
718
719 // PayPal Checkout: rr=0 with no trial/initial should behave like Buy Now (one-time),
720 // so s2Member’s standard Buy Now/EOT routines run (mirrors other gateways).
721 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled()
722 && (string)$attr["rr"] === '0'
723 && (float)$attr["ta"] <= 0
724 && (int)$attr["tp"] <= 0)
725 {
726 $attr["rr"] = 'BN';
727 }
728
729 $attr["level_ccaps_eotper"] = ($attr["rr"] === "BN" && $attr["rt"] !== "L") ? $attr["level"] . ":" . $attr["ccaps"] . ":" . $attr["rp"] . " " . $attr["rt"] : $attr["level"] . ":" . $attr["ccaps"];
730 $attr["level_ccaps_eotper"] = /* Clean any trailing separators from this string. */ rtrim ($attr["level_ccaps_eotper"], ":");
731
732 $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"]));
733
734 $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);
735 $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);
736 $success_return_url = apply_filters("ws_plugin__s2member_during_sc_paypal_button_success_return_url", $success_return_url, get_defined_vars ());
737
738 //260106 PayPal Checkout (REST) Buy Now (rr=BN) override.
739 // Uses server-side create + server-side capture/confirm, then posts into existing IPN + Return handlers.
740 if(c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_enabled())
741 {
742 $ppco_sandbox = c_ws_plugin__s2member_paypal_utilities::paypal_checkout_is_sandbox();
743 $ppco_client_id = (string)$GLOBALS["WS_PLUGIN__"]["s2member"]["o"][($ppco_sandbox) ? "paypal_checkout_sandbox_client_id" : "paypal_checkout_client_id"];
744
745 $ppco_cc = strtoupper((string)$attr["cc"]);
746 $ppco_intent = ($attr["rr"] === "BN") ? 'capture' : 'subscription';
747
748 $ppco_sdk_key = (($ppco_sandbox) ? 'sandbox' : 'live').'|'.$ppco_cc.'|'.$ppco_intent;
749
750 $ppco_sdk_just_loaded = false;
751 if(empty($ppco_sdks[$ppco_sdk_key]) || !is_array($ppco_sdks[$ppco_sdk_key]))
752 {
753 $ppco_sdks[$ppco_sdk_key] = array(
754 'ns' => 's2m_ppco_'.substr(md5($ppco_sdk_key), 0, 10),
755 'id' => 's2member_ppco_sdk_'.substr(md5($ppco_sdk_key), 0, 10),
756 );
757 $ppco_sdk_just_loaded = true;
758 }
759
760 $ppco_sdk_ns = (string)$ppco_sdks[$ppco_sdk_key]['ns'];
761 $ppco_sdk_id = (string)$ppco_sdks[$ppco_sdk_key]['id'];
762
763 $ppco_endpoint = home_url("/?s2member_paypal_checkout=1", $force_notify_url_scheme);
764 $ppco_cancel = home_url("/");
765
766 $ppco_token = array(
767 'exp' => time() + 3600,
768
769 'invoice' => $paypal_invoice_input_value,
770 'ip' => c_ws_plugin__s2member_utils_ip::current(),
771 'item_name' => $attr["desc"],
772 'item_number' => $attr["level_ccaps_eotper"],
773 'custom' => $attr["custom"],
774
775 'amount' => $attr["ra"],
776 'cc' => $ppco_cc,
777 'ns' => $attr["ns"],
778
779 'rr' => $attr["rr"],
780 'rp' => $attr["rp"],
781 'rt' => $attr["rt"],
782
783 'rrt' => $attr["rrt"],
784 'rra' => $attr["rra"],
785
786 'ta' => $attr["ta"],
787 'tp' => $attr["tp"],
788 'tt' => $attr["tt"],
789
790 'on0' => $paypal_on0_input_value,
791 'os0' => $paypal_os0_input_value,
792 'on1' => $paypal_on1_input_value,
793 'os1' => $paypal_os1_input_value,
794
795 'old__subscr_gateway' => get_user_option('s2member_subscr_gateway'),
796 'old__subscr_id' => get_user_option('s2member_subscr_id'),
797 'old__subscr_baid' => get_user_option('s2member_subscr_baid'),
798 'old__subscr_cid' => get_user_option('s2member_subscr_cid'),
799 '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.
800
801 'return' => $success_return_url,
802 'cancel' => $ppco_cancel,
803
804 'checksum' => md5($paypal_invoice_input_value.c_ws_plugin__s2member_utils_ip::current().$attr["level_ccaps_eotper"]),
805 );
806
807 $ppco_token = urlencode(c_ws_plugin__s2member_utils_encryption::encrypt(serialize($ppco_token)));
808
809 // output="anchor|url" support (no JS SDK; redirects through s2Member, then to PayPal approval URL).
810 if($attr["output"] === "anchor" || $attr["output"] === "url")
811 {
812 $ppco_redirect_url = $ppco_endpoint.'&s2member_paypal_checkout_op=redirect&s2member_paypal_checkout_t='.$ppco_token;
813
814 if($attr["output"] === "url")
815 $code = $_code = $ppco_redirect_url;
816
817 else // output="anchor"
818 {
819 $img_src = ($attr["image"] && $attr["image"] !== "default") ? $attr["image"] : $default_image;
820 $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>';
821 }
822
823 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
824 do_action("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
825 unset($__refs, $__v);
826
827 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
828 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
829 }
830
831 $ppco_div_id = 's2member_ppco_btn_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
832 $ppco_err_id = 's2member_ppco_err_'.md5($paypal_invoice_input_value.$attr["level_ccaps_eotper"]);
833
834 $ppco_locale = ($attr["lang"]) ? (string)$attr["lang"] : '';
835 $ppco_lc = ($attr["lc"]) ? (string)$attr["lc"] : '';
836
837 if(!$ppco_locale && $ppco_lc)
838 {
839 $site_locale = (string)get_locale();
840 if(preg_match('/^([a-z]{2})[_-]/i', $site_locale, $m))
841 $ppco_locale = strtolower($m[1]).'_'.strtoupper($ppco_lc);
842 else
843 $ppco_locale = 'en_'.strtoupper($ppco_lc);
844 }
845
846 $ppco_locale_q = ($ppco_locale) ? '&locale='.rawurlencode($ppco_locale) : '';
847 $ppco_buyer_country_q = ($ppco_sandbox && $ppco_lc) ? '&buyer-country='.rawurlencode(strtoupper($ppco_lc)) : '';
848
849 $ppco_sdk_src = ($ppco_sandbox ? 'https://www.sandbox.paypal.com/sdk/js' : 'https://www.paypal.com/sdk/js');
850 if($ppco_intent === 'subscription')
851 $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;
852 else
853 $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
855 $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";
857
858 $ppco_sdk_src = apply_filters('ws_plugin__s2member_ppco_sdk_src', $ppco_sdk_src, get_defined_vars());
859
860 if($ppco_sdk_just_loaded)
861 {
862 $code .= '<script id="'.esc_attr($ppco_sdk_id).'" data-namespace="'.esc_attr($ppco_sdk_ns).'" src="'.esc_attr($ppco_sdk_src).'"></script>'."\n";
863 }
864
865 $code .= '<script type="text/javascript">'."\n";
866 $code .= '(function(){'."\n";
867 $code .= 'var d="'.esc_js($ppco_div_id).'";'."\n";
868 $code .= 'var e="'.esc_js($ppco_err_id).'";'."\n";
869 $code .= 'var t="'.esc_js($ppco_token).'";'."\n";
870 $code .= 'var u="'.esc_js($ppco_endpoint).'";'."\n";
871 $code .= 'var ns="'.esc_js($ppco_sdk_ns).'";'."\n";
872 $code .= 'var s="'.esc_js($ppco_sdk_src).'";'."\n";
873 $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";
876 $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 $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 if($ppco_intent === 'subscription')
879 {
880 $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 $code .= 'var planId=null;'."\n";
882 $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 $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";
885 $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 $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 }
888 else
889 {
890 $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 $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";
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},createOrder:createOrder,onApprove:onApprove,onCancel:onCancel,onError:onError}).render("#"+d);}catch(x){el.removeAttribute("data-s2m-ppco-rendered");showErr("PayPal render failed.");}});}'."\n";
895 }
896 $code .= 'if(document.readyState==="complete"){init();}else{window.addEventListener("load",init);}'."\n";
897 $code .= '})();'."\n";
898 $code .= '</script>'."\n";
899 $_code = $code;
900
901 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
902 do_action("ws_plugin__s2member_during_sc_paypal_button", get_defined_vars ());
903 unset($__refs, $__v);
904
905 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
906 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
907 }
908
909 $code = trim (c_ws_plugin__s2member_utilities::evl (file_get_contents (dirname (dirname (__FILE__)) . "/templates/buttons/paypal-checkout-button.php")));
910 $code = preg_replace ("/%%images%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["dir_url"] . "/src/images")), $code);
911 $code = preg_replace ("/%%wpurl%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr (home_url ())), $code);
912
913 $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);
914 $code = preg_replace ("/%%paypal_business%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_business"])), $code);
915 $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);
916 $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);
917 $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.
918 $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);
919 $code = preg_replace ("/%%return%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($success_return_url)), $code);
920 $code = preg_replace ("/%%custom%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])), $code);
921 $code = preg_replace ("/%%level%%/", c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["level"])), $code);
922
923 $code = preg_replace ('/ \<\!--(\<input type\="hidden" name\="(amount|src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)--\>/', " $1", $code);
924 $code = ($attr["rr"] === "BN") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick$3", $code) : $code;
925 $code = ($attr["rr"] === "BN") ? preg_replace ('/ (\<input type\="hidden" name\="(src|srt|sra|a1|p1|t1|a3|p3|t3)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
926 $code = ($attr["rr"] === "BN" || !$attr["tp"]) ? preg_replace ('/ (\<input type\="hidden" name\="(a1|p1|t1)" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
927 $code = ($attr["rr"] !== "BN") ? preg_replace ('/ (\<input type\="hidden" name\="cmd" value\=")(.*?)(" \/\>)/', " $1_xclick-subscriptions$3", $code) : $code;
928 $code = ($attr["rr"] !== "BN") ? preg_replace ('/ (\<input type\="hidden" name\="amount" value\="(.*?)" \/\>)/', " <!--$1-->", $code) : $code;
929
930 $code = preg_replace ('/ name\="lc" value\="(.*?)"/', ' name="lc" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["lc"])) . '"', $code);
931 $code = preg_replace ('/ name\="no_shipping" value\="(.*?)"/', ' name="no_shipping" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ns"])) . '"', $code);
932 $code = preg_replace ('/ name\="item_name" value\="(.*?)"/', ' name="item_name" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["desc"])) . '"', $code);
933 $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);
934 $code = preg_replace ('/ name\="page_style" value\="(.*?)"/', ' name="page_style" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ps"])) . '"', $code);
935 $code = preg_replace ('/ name\="currency_code" value\="(.*?)"/', ' name="currency_code" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["cc"])) . '"', $code);
936 $code = preg_replace ('/ name\="custom" value\="(.*?)"/', ' name="custom" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["custom"])) . '"', $code);
937
938 $code = preg_replace ('/ name\="invoice" value\="(.*?)"/', ' name="invoice" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_invoice_input_value)) . '"', $code);
939
940 $code = preg_replace ('/ name\="on0" value\="(.*?)"/', ' name="on0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on0_input_value)) . '"', $code);
941 $code = preg_replace ('/ name\="os0" value\="(.*?)"/', ' name="os0" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os0_input_value)) . '"', $code);
942 $code = preg_replace ('/ name\="on1" value\="(.*?)"/', ' name="on1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_on1_input_value)) . '"', $code);
943 $code = preg_replace ('/ name\="os1" value\="(.*?)"/', ' name="os1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($paypal_os1_input_value)) . '"', $code);
944
945 $code = preg_replace ('/ name\="modify" value\="(.*?)"/', ' name="modify" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["modify"])) . '"', $code);
946
947 $code = preg_replace ('/ name\="amount" value\="(.*?)"/', ' name="amount" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
948
949 $code = preg_replace ('/ name\="src" value\="(.*?)"/', ' name="src" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rr"])) . '"', $code);
950 $code = preg_replace ('/ name\="srt" value\="(.*?)"/', ' name="srt" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rrt"])) . '"', $code);
951 $code = preg_replace ('/ name\="sra" value\="(.*?)"/', ' name="sra" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rra"])) . '"', $code);
952
953 $code = preg_replace ('/ name\="a1" value\="(.*?)"/', ' name="a1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ta"])) . '"', $code);
954 $code = preg_replace ('/ name\="p1" value\="(.*?)"/', ' name="p1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["tp"])) . '"', $code);
955 $code = preg_replace ('/ name\="t1" value\="(.*?)"/', ' name="t1" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["tt"])) . '"', $code);
956 $code = preg_replace ('/ name\="a3" value\="(.*?)"/', ' name="a3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["ra"])) . '"', $code);
957 $code = preg_replace ('/ name\="p3" value\="(.*?)"/', ' name="p3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rp"])) . '"', $code);
958 $code = preg_replace ('/ name\="t3" value\="(.*?)"/', ' name="t3" value="' . c_ws_plugin__s2member_utils_strings::esc_refs (esc_attr ($attr["rt"])) . '"', $code);
959
960 $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);
961
962 $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;
963 $code = ($attr["output"] === "url") ? c_ws_plugin__s2member_utils_forms::form_whips_2_url ($code) : $code;
964
965 foreach(array_keys(get_defined_vars())as$__v)$__refs[$__v]=&$$__v;
966 ($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 ());
967 unset($__refs, $__v);
968 }
969 $code = c_ws_plugin__s2member_sc_paypal_button_e::sc_paypal_button_encryption ($code, get_defined_vars ());
970
971 return apply_filters("ws_plugin__s2member_sc_paypal_button", $code, get_defined_vars ());
972 }
973 }
974 }
975