PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / 4.16.19
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress v4.16.19
4.16.19 4.16.18 4.16.17 4.16.16 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5a 1.1.6 1.1.7 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4 1.4.1 1.4.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.7.1 1.7.2 1.8 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.1.9 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.2 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.13.4 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.15.0 4.15.1 4.15.10 4.15.11 4.15.12 4.15.13 4.15.14 4.15.15 4.15.16 4.15.17 4.15.18 4.15.19 4.15.2 4.15.20 4.15.20.1 4.15.21 4.15.22 4.15.23 4.15.24 4.15.25 4.15.3 4.15.4 4.15.5 4.15.6 4.15.7 4.15.8 4.15.9 4.16.0 4.16.1 4.16.10 4.16.11 4.16.12 4.16.13 4.16.14 4.16.15 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.2.0 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.7.0 4.8.0 4.9.0
wp-user-avatar / src / Membership / PaymentMethods / Stripe / PaymentHelpers.php
wp-user-avatar / src / Membership / PaymentMethods / Stripe Last commit date
WebhookHandlers 4 months ago APIClass.php 3 years ago Helpers.php 1 month ago PaymentHelpers.php 3 months ago Stripe.php 2 months ago WebhookHelpers.php 8 months ago index.php 3 years ago
PaymentHelpers.php
387 lines
1 <?php
2
3 namespace ProfilePress\Core\Membership\PaymentMethods\Stripe;
4
5 use ProfilePress\Core\Classes\ExtensionManager;
6 use ProfilePress\Core\Membership\CheckoutFields;
7 use ProfilePress\Core\Membership\Models\Customer\CustomerEntity;
8 use ProfilePress\Core\Membership\Models\Plan\PlanFactory;
9 use ProfilePress\Core\Membership\Models\Subscription\SubscriptionBillingFrequency;
10 use ProfilePress\Core\Membership\Models\Subscription\SubscriptionEntity;
11 use ProfilePress\Core\Membership\Models\Subscription\SubscriptionTrialPeriod;
12 use ProfilePress\Core\Membership\Services\Calculator;
13 use ProfilePressVendor\Carbon\CarbonImmutable;
14
15 class PaymentHelpers
16 {
17 public static function add_coupon_to_bucket($stripe_coupon_id)
18 {
19 $data = \get_option('ppress_stripe_coupon_bucket', []);
20 $data[$stripe_coupon_id] = time() + (24 * HOUR_IN_SECONDS);
21 \update_option('ppress_stripe_coupon_bucket', $data);
22 }
23
24 public static function empty_coupon_bucket()
25 {
26 $data = \get_option('ppress_stripe_coupon_bucket', []);
27
28 if ( ! empty($data)) {
29
30 foreach ($data as $coupon_id => $time) {
31 if (time() >= $time) {
32 self::delete_coupon($coupon_id);
33 unset($data[$coupon_id]);
34 }
35 }
36
37 \update_option('ppress_stripe_coupon_bucket', $data);
38 }
39 }
40
41 public static function delete_coupon($stripe_coupon_id)
42 {
43 try {
44 APIClass::stripeClient()->coupons->delete($stripe_coupon_id);
45 } catch (\Exception $e) {
46 }
47 }
48
49 /**
50 * @return string
51 */
52 public static function get_signup_fee_label()
53 {
54 return apply_filters('ppress_stripe_signup_fee_label', __('Setup Fee', 'wp-user-avatar'));
55 }
56
57 public static function stripe_amount_to_ppress_amount($amount, $currency = '')
58 {
59 if ( ! self::is_zero_decimal_currency($currency)) {
60 $amount = ppress_cent_to_decimal($amount);
61 }
62
63 return $amount;
64 }
65
66 /**
67 * @param string $freeTrial
68 *
69 * @return int
70 */
71 public static function free_trial_days_count($freeTrial)
72 {
73 switch ($freeTrial) {
74 case SubscriptionTrialPeriod::THREE_DAYS:
75 return 3;
76 case SubscriptionTrialPeriod::FIVE_DAYS:
77 return 5;
78 case SubscriptionTrialPeriod::ONE_WEEK:
79 return 7;
80 case SubscriptionTrialPeriod::TWO_WEEKS:
81 return 14;
82 case SubscriptionTrialPeriod::THREE_WEEKS:
83 return 21;
84 case SubscriptionTrialPeriod::ONE_MONTH:
85 return CarbonImmutable::now('UTC')->diffInDays(
86 CarbonImmutable::now('UTC')->addMonth()
87 );
88 }
89
90 return 0;
91 }
92
93 /**
94 * @param SubscriptionEntity $subscription
95 *
96 * @return mixed
97 *
98 * @throws \Exception
99 */
100 public static function get_product_price($subscription, $statement_descriptor)
101 {
102 switch ($subscription->billing_frequency) {
103
104 case SubscriptionBillingFrequency::DAILY :
105 $frequency = 1;
106 $period = 'day';
107 break;
108 case SubscriptionBillingFrequency::MONTHLY :
109 $frequency = 1;
110 $period = 'month';
111 break;
112 case SubscriptionBillingFrequency::WEEKLY :
113 $frequency = 1;
114 $period = 'week';
115 break;
116 case SubscriptionBillingFrequency::QUARTERLY :
117 $frequency = 3;
118 $period = 'month';
119 break;
120 case SubscriptionBillingFrequency::EVERY_6_MONTHS :
121 $frequency = 6;
122 $period = 'month';
123 break;
124 case SubscriptionBillingFrequency::YEARLY :
125 $frequency = 1;
126 $period = 'year';
127 break;
128 default :
129 $frequency = 1;
130 $period = $subscription->billing_frequency;
131 break;
132 }
133
134 $frequency = apply_filters('ppress_stripe_billing_frequency_interval', $frequency, $subscription->billing_frequency, $subscription);
135 $period = apply_filters('ppress_stripe_billing_period_interval_count', $period, $subscription->billing_frequency, $subscription);
136
137 $stripe_product_id = 'ppress_prod_' . ppress_md5($subscription->plan_id);
138
139 $plan = PlanFactory::fromId($subscription->plan_id);
140
141 $is_recurring = $plan->is_auto_renew();
142
143 try {
144
145 APIClass::stripeClient()->products->retrieve($stripe_product_id);
146
147 } catch (\Exception $e) {
148
149 $create_product_args = [
150 'id' => $stripe_product_id,
151 'name' => $plan->name,
152 'description' => strip_tags(sanitize_textarea_field($plan->description)),
153 'metadata' => [
154 'plan_id' => $plan->id,
155 'caller' => __CLASS__ . '|' . __METHOD__ . '|' . __LINE__ . '|' . PPRESS_VERSION_NUMBER,
156 ]
157 ];
158
159 if ( ! empty($statement_descriptor)) {
160 $create_product_args['statement_descriptor'] = $statement_descriptor;
161 }
162
163 $create_product_args = array_filter(apply_filters('ppress_stripe_create_product_args', $create_product_args, $subscription));
164
165 try {
166 APIClass::stripeClient()->products->create($create_product_args)->toArray();
167 } catch (\Exception $e) {
168
169 }
170 }
171
172 $price_args = [
173 'currency' => ppress_get_currency(),
174 'product' => $stripe_product_id,
175 'unit_amount' => self::process_amount($subscription->get_recurring_amount()),
176 ];
177
178 if ( ! $plan->is_auto_renew()) {
179 $price_args['unit_amount'] = self::process_amount($subscription->initial_amount);
180 }
181
182 if ($is_recurring === true) {
183
184 $price_args['recurring'] = array(
185 'interval' => $period,
186 'interval_count' => $frequency
187 );
188 }
189
190 $price_args = apply_filters('ppress_stripe_create_price_args', $price_args, $subscription, $plan);
191
192 $stripe_price_id = ppress_md5(wp_json_encode($price_args));
193
194 $price_args['metadata'] = [
195 'ppress_price_id' => $stripe_price_id,
196 'caller' => __CLASS__ . '|' . __METHOD__ . '|' . __LINE__ . '|' . PPRESS_VERSION_NUMBER,
197 ];
198
199 $price_search_args = [
200 'product' => $stripe_product_id,
201 'type' => $is_recurring ? 'recurring' : 'one_time',
202 ];
203
204 if ($is_recurring) {
205 $price_search_args['recurring'] = array('interval' => $period);
206 }
207
208 $price_search_args = apply_filters('ppress_stripe_price_search_args', $price_search_args, $subscription, $plan);
209
210 $stripe_prices = APIClass::stripeClient()->prices->all($price_search_args)->toArray();
211
212 if ( ! empty($stripe_prices['data']) && is_array($stripe_prices['data'])) {
213
214 foreach ($stripe_prices['data'] as $price) {
215 if (isset($price['metadata']['ppress_price_id']) && $price['metadata']['ppress_price_id'] == $stripe_price_id) {
216 return [
217 'stripe_product_id' => $stripe_product_id,
218 'stripe_price_id' => $price['id']
219 ];
220 }
221 }
222 }
223
224 try {
225 $created_price = APIClass::stripeClient()->prices->create($price_args)->toArray();
226 } catch (\Exception $e) {
227 throw new \Exception($e->getMessage(), $e->getCode());
228 }
229
230 return [
231 'stripe_product_id' => $stripe_product_id,
232 'stripe_price_id' => $created_price['id']
233 ];
234 }
235
236 /**
237 * @param CustomerEntity $customer
238 *
239 * @return int
240 *
241 * @throws \Exception
242 */
243 public static function get_stripe_customer_id($customer)
244 {
245 try {
246
247 $search_result = APIClass::stripeClient()->customers->search([
248 'query' => sprintf('email:\'%s\' AND metadata[\'ppress_customer_id\']:\'%s\'', $customer->get_email(), $customer->id)
249 ])->toArray();
250
251 if ( ! empty($search_result['data']) && isset($search_result['data'][0]['id'])) {
252 return $search_result['data'][0]['id'];
253 }
254
255 } catch (\Exception $e) {
256
257 $stripe_customer_id = $customer->get_meta('stripe_customer_id');
258
259 if ( ! empty($stripe_customer_id)) return $stripe_customer_id;
260 }
261
262 $pp_customer_billing = $customer->get_billing_details();
263
264 $create_customer_args = [
265 'email' => $customer->get_email(),
266 'name' => $customer->get_name()
267 ];
268
269 if ( ! empty($pp_customer_billing)) {
270
271 $create_customer_args['address'] = [];
272
273 if ( ! empty($pp_customer_billing[CheckoutFields::BILLING_CITY])) {
274 $create_customer_args['address']['city'] = $pp_customer_billing[CheckoutFields::BILLING_CITY];
275 }
276
277 if ( ! empty($pp_customer_billing[CheckoutFields::BILLING_COUNTRY])) {
278 $create_customer_args['address']['country'] = $pp_customer_billing[CheckoutFields::BILLING_COUNTRY];
279 }
280
281 if ( ! empty($pp_customer_billing[CheckoutFields::BILLING_ADDRESS])) {
282 $create_customer_args['address']['line1'] = $pp_customer_billing[CheckoutFields::BILLING_ADDRESS];
283 }
284
285 if ( ! empty($pp_customer_billing[CheckoutFields::BILLING_POST_CODE])) {
286 $create_customer_args['address']['postal_code'] = $pp_customer_billing[CheckoutFields::BILLING_POST_CODE];
287 }
288
289 if ( ! empty($pp_customer_billing[CheckoutFields::BILLING_STATE])) {
290 $create_customer_args['address']['state'] = $pp_customer_billing[CheckoutFields::BILLING_STATE];
291 }
292 }
293
294 $create_customer_args['metadata'] = apply_filters('ppress_stripe_customer_metadata', [
295 'ppress_customer_id' => $customer->id,
296 'caller' => __CLASS__ . '|' . __METHOD__ . '|' . __LINE__ . '|' . PPRESS_VERSION_NUMBER,
297 ], $customer, $create_customer_args);
298
299 $create_customer_args = apply_filters('ppress_create_customer_args', $create_customer_args, $customer);
300
301 $created_customer = APIClass::stripeClient()->customers->create($create_customer_args)->toArray();
302
303 $stripe_customer_id = ppress_var($created_customer, 'id');
304
305 $customer->update_meta('stripe_customer_id', $stripe_customer_id);
306
307 return $stripe_customer_id;
308 }
309
310 public static function is_zero_decimal_currency($currency = '')
311 {
312 if (empty($currency)) {
313 $currency = ppress_get_currency();
314 }
315
316 $currency = strtolower($currency);
317
318 $currencies = [
319 'bif',
320 'clp',
321 'djf',
322 'gnf',
323 'jpy',
324 'kmf',
325 'krw',
326 'mga',
327 'pyg',
328 'rwf',
329 'ugx',
330 'vnd',
331 'vuv',
332 'xaf',
333 'xof',
334 'xpf',
335 ];
336
337 return in_array($currency, $currencies, true);
338 }
339
340 public static function process_amount($price, $currency = '')
341 {
342 if ( ! self::is_zero_decimal_currency($currency)) {
343 $price = Calculator::init($price)->toScale(2)->multipliedBy(100)->val();
344 }
345
346 return Calculator::init($price)->toScale(0)->val();
347 }
348
349 public static function application_fee_percent()
350 {
351 return 2;
352 }
353
354 public static function application_fee_amount($order_total)
355 {
356 return self::process_amount(
357 Calculator::init($order_total)->multipliedBy('0.02')->val()
358 );
359 }
360
361 public static function has_application_fee()
362 {
363 if (ExtensionManager::is_premium()) return false;
364
365 $account_country = ppress_business_country('US');
366
367 /**
368 * Do not add a fee if account country does not support application fees.
369 * @see https://stripe.com/docs/connect/direct-charges#collecting-fees
370 * @see https://groups.google.com/a/lists.stripe.com/g/api-discuss/c/-Ezjn3roCiI/m/MYUpA4kUAQAJ
371 */
372 $disallowed_list = [
373 'br'
374 /** @see https://stripe.com/docs/connect/direct-charges#collecting-fees */,
375 'in',
376 // Error: Stripe doesn't currently support application fees for platforms in US with connected accounts in IN|MY|MX
377 'mx',
378 'my'
379 ];
380
381 if (in_array(strtolower($account_country), $disallowed_list, true)) {
382 return false;
383 }
384
385 return true;
386 }
387 }