Completed
Branch master (fee289)
by
unknown
10:28 queued 04:32
created
PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php 2 patches
Indentation   +418 added lines, -418 removed lines patch added patch discarded remove patch
@@ -33,423 +33,423 @@
 block discarded – undo
33 33
  */
34 34
 class CreateOrder extends OrdersApi
35 35
 {
36
-    /**
37
-     * Line items total.
38
-     *
39
-     * @var float
40
-     */
41
-    protected float $items_total = 0.0;
42
-
43
-    /**
44
-     * Promotions total.
45
-     *
46
-     * @var float
47
-     */
48
-    protected float $promos_total = 0.0;
49
-
50
-    /**
51
-     * Tax total.
52
-     *
53
-     * @var float
54
-     */
55
-    protected float $tax_total = 0.0;
56
-
57
-    /**
58
-     * Currency.
59
-     *
60
-     * @var string
61
-     */
62
-    protected string $currency_code;
63
-
64
-    /**
65
-     * Billing info.
66
-     *
67
-     * @var array
68
-     */
69
-    protected array $billing_info;
70
-
71
-    /**
72
-     * Transaction this order is for.
73
-     *
74
-     * @var EE_Transaction
75
-     */
76
-    protected EE_Transaction $transaction;
77
-
78
-    private FeatureFlags $feature;
79
-
80
-    private GatewayDataFormatter $gateway_data_formatter;
81
-
82
-    private EE_Payment $payment;
83
-
84
-    /**
85
-     * CreateOrder constructor.
86
-     *
87
-     * @param PayPalApi      $api
88
-     * @param EE_Transaction $transaction
89
-     * @param array          $billing_info
90
-     * @param FeatureFlags   $feature
91
-     */
92
-    public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info, FeatureFlags $feature, GatewayDataFormatter $gateway_data_formatter)
93
-    {
94
-        parent::__construct($api);
95
-        $this->transaction   = $transaction;
96
-        $this->feature       = $feature;
97
-        $this->currency_code = CurrencyManager::currencyCode();
98
-        $this->sanitizeRequestParameters($billing_info);
99
-        $this->gateway_data_formatter = $gateway_data_formatter;
100
-        $this->setPaymentPlaceholder();
101
-    }
102
-
103
-
104
-    /**
105
-     * Sanitize the array of billing form data.
106
-     *
107
-     * @param array $billing_info
108
-     * @return void
109
-     */
110
-    public function sanitizeRequestParameters(array $billing_info): void
111
-    {
112
-        $sanitizer = new RequestSanitizer(new Basic());
113
-        foreach ($billing_info as $item => $value) {
114
-            $this->billing_info[ $item ] = $sanitizer->clean($value);
115
-        }
116
-    }
117
-
118
-
119
-    /**
120
-     * Create PayPal Order.
121
-     *
122
-     * @return array
123
-     * @throws EE_Error
124
-     * @throws ReflectionException
125
-     */
126
-    public function create(): array
127
-    {
128
-        $order_parameters = $this->getParameters();
129
-        // Create Order request.
130
-        $create_response = $this->api->sendRequest($order_parameters, $this->request_url);
131
-        // Check for MISMATCH errors.
132
-        if ($this->isMismatchError($create_response)) {
133
-            // Mismatch, fix items.
134
-            $order_parameters['purchase_units'][0]['items'] = $this->getSimplifiedItems();
135
-            // Add simplified breakdown.
136
-            $order_parameters['purchase_units'][0]['amount']['breakdown'] = $this->getSimplifiedAmountBreakdown();
137
-            // Retry Order request.
138
-            $create_response = $this->api->sendRequest($order_parameters, $this->request_url);
139
-        }
140
-        return $this->validateOrder($create_response, $order_parameters);
141
-    }
142
-
143
-
144
-    /**
145
-     * Form order parameters.
146
-     *
147
-     * @return array
148
-     * @throws EE_Error
149
-     * @throws ReflectionException
150
-     * @throws Exception
151
-     */
152
-    protected function getParameters(): array
153
-    {
154
-        $registrant  = $this->transaction->primary_registration();
155
-        $attendee    = $registrant->attendee();
156
-        $event       = $registrant->event();
157
-        $description = $this->gateway_data_formatter->formatOrderDescription($this->payment);
158
-        $parameters  = [
159
-            'intent'              => 'CAPTURE',
160
-            'purchase_units'      => [
161
-                [
162
-                    'custom_id'   => $this->transaction->ID(),
163
-                    'description' => substr(wp_strip_all_tags($description), 0, 125),
164
-                    'items'       => $this->getLineItems(),
165
-                    'amount'      => [
166
-                        'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining()),
167
-                        'currency_code' => $this->currency_code,
168
-                        'breakdown'     => $this->getBreakdown(),
169
-                    ],
170
-                ],
171
-            ],
172
-            'payment_source' => [
173
-                'paypal' => [
174
-                    'experience_context' => [
175
-                        'user_action' => 'PAY_NOW',
176
-                    ],
177
-                    'email_address' => $attendee->email(),
178
-                    'name'  => [
179
-                        'given_name' => $attendee->fname(),
180
-                        'surname' => $attendee->lname(),
181
-                    ],
182
-                ],
183
-            ],
184
-        ];
185
-
186
-        // If we have and address on the attendee, send it to PayPal.
187
-        if($attendee->country_ID()) {
188
-            $parameters['payment_source']['paypal']['address'] = [
189
-                'address_line_1'    => $attendee->address(),
190
-                'address_line_2'    => $attendee->address2(),
191
-                'admin_area_2'      => $attendee->city(),
192
-                'admin_area_1'      => $attendee->state_abbrev(),
193
-                'postal_code'       => $attendee->zip(),
194
-                'country_code'      => $attendee->country_ID(),
195
-            ];
196
-        }
197
-
198
-        // Do we have the permissions for the fees ?
199
-        $scopes = PayPalExtraMetaManager::getPmOption(
200
-            $this->transaction->payment_method(),
201
-            Domain::META_KEY_AUTHORIZED_SCOPES
202
-        );
203
-        if (
204
-            (
205
-                (defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES)
206
-                || (! defined('EE_PPC_USE_PAYMENT_FEES')
207
-                    && $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES)
208
-                )
209
-            )
210
-            && ! empty($scopes) && in_array('partnerfee', $scopes)
211
-        ) {
212
-            /** @var PartnerPaymentFees $payment_fees */
213
-            $payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class);
214
-            $parameters['purchase_units'][0]['payment_instruction'] = [
215
-                'platform_fees' => [
216
-                    [
217
-                        'amount' => [
218
-                            'value'         => (string) $payment_fees->getPartnerFee($this->transaction),
219
-                            'currency_code' => $this->currency_code,
220
-                        ],
221
-                    ],
222
-                ]
223
-            ];
224
-        }
225
-        return $parameters;
226
-    }
227
-
228
-
229
-    /**
230
-     * Itemize the payment. List all the line items, discounts and taxes.
231
-     *
232
-     * @return array
233
-     * @throws EE_Error|ReflectionException
234
-     */
235
-    protected function getLineItems(): array
236
-    {
237
-        // Order line items.
238
-        $line_items       = [];
239
-        $event_line_items = $this->transaction->items_purchased();
240
-        // List actual line items.
241
-        foreach ($event_line_items as $line_item) {
242
-            if (
243
-                $line_item instanceof EE_Line_Item
244
-                && $line_item->OBJ_type() !== 'Promotion'
245
-                && $line_item->quantity() > 0
246
-            ) {
247
-                $item_money     = CurrencyManager::normalizeValue($line_item->unit_price());
248
-                $line_items []  = [
249
-                    'name'        => substr(wp_strip_all_tags($this->gateway_data_formatter->formatLineItemName($line_item, $this->payment)), 0, 125),
250
-                    'quantity'    => $line_item->quantity(),
251
-                    'description' => substr(wp_strip_all_tags($this->gateway_data_formatter->formatLineItemDesc($line_item, $this->payment)), 0, 125),
252
-                    'unit_amount' => [
253
-                        'currency_code' => $this->currency_code,
254
-                        'value'         => (string) $item_money,
255
-                    ],
256
-                    'category'    => 'DIGITAL_GOODS',
257
-                ];
258
-                // Line item total.
259
-                $this->items_total += $line_item->pretaxTotal();
260
-            } elseif ($line_item->OBJ_type() === 'Promotion' && $line_item->quantity() > 0) {
261
-                // Promotions total.
262
-                $this->promos_total += $line_item->total();
263
-            }
264
-        }
265
-        // Make sure we have an absolute number with only two decimal laces.
266
-        $this->items_total  = CurrencyManager::normalizeValue($this->items_total);
267
-        $this->promos_total = CurrencyManager::normalizeValue($this->promos_total);
268
-        // If this is a partial payment, apply the paid amount as a promo.
269
-        if ($this->transaction->paid() > 0) {
270
-            $this->promos_total += CurrencyManager::normalizeValue($this->transaction->paid());
271
-        }
272
-        $this->countTaxTotal();
273
-        return $line_items;
274
-    }
275
-
276
-
277
-    /**
278
-     * Count the tax total.
279
-     *
280
-     * @return void
281
-     * @throws EE_Error|ReflectionException
282
-     */
283
-    protected function countTaxTotal(): void
284
-    {
285
-        // List taxes.
286
-        $this->tax_total = 0.0;
287
-        $tax_items       = $this->transaction->tax_items();
288
-        foreach ($tax_items as $tax_item) {
289
-            $this->tax_total += $tax_item->total();
290
-        }
291
-        $this->tax_total = CurrencyManager::normalizeValue($this->tax_total);
292
-    }
293
-
294
-
295
-    /**
296
-     * Itemize the payment the breakdown list.
297
-     *
298
-     * @return array
299
-     */
300
-    protected function getBreakdown(): array
301
-    {
302
-        $breakdown['item_total'] = [
303
-            'currency_code' => $this->currency_code,
304
-            'value'         => (string) $this->items_total,
305
-        ];
306
-        $breakdown['tax_total']  = [
307
-            'currency_code' => $this->currency_code,
308
-            'value'         => (string) $this->tax_total,
309
-        ];
310
-        $breakdown['discount']   = [
311
-            'currency_code' => $this->currency_code,
312
-            'value'         => (string) abs($this->promos_total),
313
-        ];
314
-        return $breakdown;
315
-    }
316
-
317
-
318
-    /**
319
-     * Makes sure that we have received an Order back from the API call.
320
-     *
321
-     * @param $response
322
-     * @param $parameters
323
-     * @return array
324
-     * @throws EE_Error
325
-     * @throws ReflectionException
326
-     */
327
-    public function validateOrder($response, $parameters): array
328
-    {
329
-        PayPalLogger::errorLog(
330
-            esc_html__('Validating Order Create:', 'event_espresso'),
331
-            [$this->request_url, $response],
332
-            $this->transaction->payment_method(),
333
-            false,
334
-            $this->transaction
335
-        );
336
-        if (! empty($response['error'])) {
337
-            return $response;
338
-        }
339
-        if (! isset($response['id'])) {
340
-            $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso');
341
-            try {
342
-                PayPalLogger::errorLog(
343
-                    $message,
344
-                    [$this->request_url, $parameters, $response],
345
-                    $this->transaction->payment_method()
346
-                );
347
-            } catch (EE_Error | ReflectionException $e) {
348
-                error_log("PayPalLogger Error: $message: " . json_encode($response));
349
-            }
350
-            return [
351
-                'error'    => $response['error'] ?? 'missing_order',
352
-                'message'  => $response['message'] ?? $message,
353
-                'response' => $response,
354
-            ];
355
-        }
356
-        return $response;
357
-    }
358
-
359
-
360
-    /**
361
-     * Check if PayPals response contains 'MISMATCH' errors.
362
-     *
363
-     * @return bool
364
-     */
365
-    public function isMismatchError($response): bool
366
-    {
367
-        if (! isset($response['details']) || ! is_array($response['details'])) {
368
-            return false;
369
-        }
370
-
371
-        foreach($response['details'] as $detail) {
372
-            if (! empty($detail['issue'])) {
373
-                if (
374
-                    strtoupper($detail['issue']) === 'ITEM_TOTAL_MISMATCH'
375
-                    || strtoupper($detail['issue']) === 'AMOUNT_MISMATCH'
376
-            ) {
377
-                    PayPalLogger::errorLog(
378
-                        esc_html__('Mistmatch Error:', 'event_espresso'),
379
-                        [$this->request_url, $response],
380
-                        $this->transaction->payment_method(),
381
-                        false,
382
-                        $this->transaction
383
-                    );
384
-                    return true;
385
-                }
386
-            }
387
-        }
388
-        return false;
389
-    }
390
-
391
-
392
-    /**
393
-     * Itemize the simplified payment breakdown list.
394
-     *
395
-     * @return array
396
-     */
397
-    protected function getSimplifiedAmountBreakdown(): array
398
-    {
399
-        $tax_total = $this->transaction->tax_total();
400
-        $breakdown['item_total'] = [
401
-            'currency_code' => $this->currency_code,
402
-            'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining() - $tax_total)
403
-        ];
404
-        if ($tax_total > 0) {
405
-            $breakdown['tax_total'] = [
406
-                'currency_code' => $this->currency_code,
407
-                'value'         => (string) CurrencyManager::normalizeValue($tax_total)
408
-            ];
409
-        }
410
-        return $breakdown;
411
-    }
412
-
413
-
414
-    /**
415
-     * Generate single line item for full order.
416
-     *
417
-     * @return array
418
-     */
419
-    protected function getSimplifiedItems(): array
420
-    {
421
-        // Simplified single line item.
422
-        $line_items             = [];
423
-        $primary_registrant     = $this->transaction->primary_registration();
424
-        $event_obj              = $primary_registrant->event_obj();
425
-        $name_and_description   = $this->gateway_data_formatter->formatOrderDescription($this->payment);
36
+	/**
37
+	 * Line items total.
38
+	 *
39
+	 * @var float
40
+	 */
41
+	protected float $items_total = 0.0;
42
+
43
+	/**
44
+	 * Promotions total.
45
+	 *
46
+	 * @var float
47
+	 */
48
+	protected float $promos_total = 0.0;
49
+
50
+	/**
51
+	 * Tax total.
52
+	 *
53
+	 * @var float
54
+	 */
55
+	protected float $tax_total = 0.0;
56
+
57
+	/**
58
+	 * Currency.
59
+	 *
60
+	 * @var string
61
+	 */
62
+	protected string $currency_code;
63
+
64
+	/**
65
+	 * Billing info.
66
+	 *
67
+	 * @var array
68
+	 */
69
+	protected array $billing_info;
70
+
71
+	/**
72
+	 * Transaction this order is for.
73
+	 *
74
+	 * @var EE_Transaction
75
+	 */
76
+	protected EE_Transaction $transaction;
77
+
78
+	private FeatureFlags $feature;
79
+
80
+	private GatewayDataFormatter $gateway_data_formatter;
81
+
82
+	private EE_Payment $payment;
83
+
84
+	/**
85
+	 * CreateOrder constructor.
86
+	 *
87
+	 * @param PayPalApi      $api
88
+	 * @param EE_Transaction $transaction
89
+	 * @param array          $billing_info
90
+	 * @param FeatureFlags   $feature
91
+	 */
92
+	public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info, FeatureFlags $feature, GatewayDataFormatter $gateway_data_formatter)
93
+	{
94
+		parent::__construct($api);
95
+		$this->transaction   = $transaction;
96
+		$this->feature       = $feature;
97
+		$this->currency_code = CurrencyManager::currencyCode();
98
+		$this->sanitizeRequestParameters($billing_info);
99
+		$this->gateway_data_formatter = $gateway_data_formatter;
100
+		$this->setPaymentPlaceholder();
101
+	}
102
+
103
+
104
+	/**
105
+	 * Sanitize the array of billing form data.
106
+	 *
107
+	 * @param array $billing_info
108
+	 * @return void
109
+	 */
110
+	public function sanitizeRequestParameters(array $billing_info): void
111
+	{
112
+		$sanitizer = new RequestSanitizer(new Basic());
113
+		foreach ($billing_info as $item => $value) {
114
+			$this->billing_info[ $item ] = $sanitizer->clean($value);
115
+		}
116
+	}
117
+
118
+
119
+	/**
120
+	 * Create PayPal Order.
121
+	 *
122
+	 * @return array
123
+	 * @throws EE_Error
124
+	 * @throws ReflectionException
125
+	 */
126
+	public function create(): array
127
+	{
128
+		$order_parameters = $this->getParameters();
129
+		// Create Order request.
130
+		$create_response = $this->api->sendRequest($order_parameters, $this->request_url);
131
+		// Check for MISMATCH errors.
132
+		if ($this->isMismatchError($create_response)) {
133
+			// Mismatch, fix items.
134
+			$order_parameters['purchase_units'][0]['items'] = $this->getSimplifiedItems();
135
+			// Add simplified breakdown.
136
+			$order_parameters['purchase_units'][0]['amount']['breakdown'] = $this->getSimplifiedAmountBreakdown();
137
+			// Retry Order request.
138
+			$create_response = $this->api->sendRequest($order_parameters, $this->request_url);
139
+		}
140
+		return $this->validateOrder($create_response, $order_parameters);
141
+	}
142
+
143
+
144
+	/**
145
+	 * Form order parameters.
146
+	 *
147
+	 * @return array
148
+	 * @throws EE_Error
149
+	 * @throws ReflectionException
150
+	 * @throws Exception
151
+	 */
152
+	protected function getParameters(): array
153
+	{
154
+		$registrant  = $this->transaction->primary_registration();
155
+		$attendee    = $registrant->attendee();
156
+		$event       = $registrant->event();
157
+		$description = $this->gateway_data_formatter->formatOrderDescription($this->payment);
158
+		$parameters  = [
159
+			'intent'              => 'CAPTURE',
160
+			'purchase_units'      => [
161
+				[
162
+					'custom_id'   => $this->transaction->ID(),
163
+					'description' => substr(wp_strip_all_tags($description), 0, 125),
164
+					'items'       => $this->getLineItems(),
165
+					'amount'      => [
166
+						'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining()),
167
+						'currency_code' => $this->currency_code,
168
+						'breakdown'     => $this->getBreakdown(),
169
+					],
170
+				],
171
+			],
172
+			'payment_source' => [
173
+				'paypal' => [
174
+					'experience_context' => [
175
+						'user_action' => 'PAY_NOW',
176
+					],
177
+					'email_address' => $attendee->email(),
178
+					'name'  => [
179
+						'given_name' => $attendee->fname(),
180
+						'surname' => $attendee->lname(),
181
+					],
182
+				],
183
+			],
184
+		];
185
+
186
+		// If we have and address on the attendee, send it to PayPal.
187
+		if($attendee->country_ID()) {
188
+			$parameters['payment_source']['paypal']['address'] = [
189
+				'address_line_1'    => $attendee->address(),
190
+				'address_line_2'    => $attendee->address2(),
191
+				'admin_area_2'      => $attendee->city(),
192
+				'admin_area_1'      => $attendee->state_abbrev(),
193
+				'postal_code'       => $attendee->zip(),
194
+				'country_code'      => $attendee->country_ID(),
195
+			];
196
+		}
197
+
198
+		// Do we have the permissions for the fees ?
199
+		$scopes = PayPalExtraMetaManager::getPmOption(
200
+			$this->transaction->payment_method(),
201
+			Domain::META_KEY_AUTHORIZED_SCOPES
202
+		);
203
+		if (
204
+			(
205
+				(defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES)
206
+				|| (! defined('EE_PPC_USE_PAYMENT_FEES')
207
+					&& $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES)
208
+				)
209
+			)
210
+			&& ! empty($scopes) && in_array('partnerfee', $scopes)
211
+		) {
212
+			/** @var PartnerPaymentFees $payment_fees */
213
+			$payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class);
214
+			$parameters['purchase_units'][0]['payment_instruction'] = [
215
+				'platform_fees' => [
216
+					[
217
+						'amount' => [
218
+							'value'         => (string) $payment_fees->getPartnerFee($this->transaction),
219
+							'currency_code' => $this->currency_code,
220
+						],
221
+					],
222
+				]
223
+			];
224
+		}
225
+		return $parameters;
226
+	}
227
+
228
+
229
+	/**
230
+	 * Itemize the payment. List all the line items, discounts and taxes.
231
+	 *
232
+	 * @return array
233
+	 * @throws EE_Error|ReflectionException
234
+	 */
235
+	protected function getLineItems(): array
236
+	{
237
+		// Order line items.
238
+		$line_items       = [];
239
+		$event_line_items = $this->transaction->items_purchased();
240
+		// List actual line items.
241
+		foreach ($event_line_items as $line_item) {
242
+			if (
243
+				$line_item instanceof EE_Line_Item
244
+				&& $line_item->OBJ_type() !== 'Promotion'
245
+				&& $line_item->quantity() > 0
246
+			) {
247
+				$item_money     = CurrencyManager::normalizeValue($line_item->unit_price());
248
+				$line_items []  = [
249
+					'name'        => substr(wp_strip_all_tags($this->gateway_data_formatter->formatLineItemName($line_item, $this->payment)), 0, 125),
250
+					'quantity'    => $line_item->quantity(),
251
+					'description' => substr(wp_strip_all_tags($this->gateway_data_formatter->formatLineItemDesc($line_item, $this->payment)), 0, 125),
252
+					'unit_amount' => [
253
+						'currency_code' => $this->currency_code,
254
+						'value'         => (string) $item_money,
255
+					],
256
+					'category'    => 'DIGITAL_GOODS',
257
+				];
258
+				// Line item total.
259
+				$this->items_total += $line_item->pretaxTotal();
260
+			} elseif ($line_item->OBJ_type() === 'Promotion' && $line_item->quantity() > 0) {
261
+				// Promotions total.
262
+				$this->promos_total += $line_item->total();
263
+			}
264
+		}
265
+		// Make sure we have an absolute number with only two decimal laces.
266
+		$this->items_total  = CurrencyManager::normalizeValue($this->items_total);
267
+		$this->promos_total = CurrencyManager::normalizeValue($this->promos_total);
268
+		// If this is a partial payment, apply the paid amount as a promo.
269
+		if ($this->transaction->paid() > 0) {
270
+			$this->promos_total += CurrencyManager::normalizeValue($this->transaction->paid());
271
+		}
272
+		$this->countTaxTotal();
273
+		return $line_items;
274
+	}
275
+
276
+
277
+	/**
278
+	 * Count the tax total.
279
+	 *
280
+	 * @return void
281
+	 * @throws EE_Error|ReflectionException
282
+	 */
283
+	protected function countTaxTotal(): void
284
+	{
285
+		// List taxes.
286
+		$this->tax_total = 0.0;
287
+		$tax_items       = $this->transaction->tax_items();
288
+		foreach ($tax_items as $tax_item) {
289
+			$this->tax_total += $tax_item->total();
290
+		}
291
+		$this->tax_total = CurrencyManager::normalizeValue($this->tax_total);
292
+	}
293
+
294
+
295
+	/**
296
+	 * Itemize the payment the breakdown list.
297
+	 *
298
+	 * @return array
299
+	 */
300
+	protected function getBreakdown(): array
301
+	{
302
+		$breakdown['item_total'] = [
303
+			'currency_code' => $this->currency_code,
304
+			'value'         => (string) $this->items_total,
305
+		];
306
+		$breakdown['tax_total']  = [
307
+			'currency_code' => $this->currency_code,
308
+			'value'         => (string) $this->tax_total,
309
+		];
310
+		$breakdown['discount']   = [
311
+			'currency_code' => $this->currency_code,
312
+			'value'         => (string) abs($this->promos_total),
313
+		];
314
+		return $breakdown;
315
+	}
316
+
317
+
318
+	/**
319
+	 * Makes sure that we have received an Order back from the API call.
320
+	 *
321
+	 * @param $response
322
+	 * @param $parameters
323
+	 * @return array
324
+	 * @throws EE_Error
325
+	 * @throws ReflectionException
326
+	 */
327
+	public function validateOrder($response, $parameters): array
328
+	{
329
+		PayPalLogger::errorLog(
330
+			esc_html__('Validating Order Create:', 'event_espresso'),
331
+			[$this->request_url, $response],
332
+			$this->transaction->payment_method(),
333
+			false,
334
+			$this->transaction
335
+		);
336
+		if (! empty($response['error'])) {
337
+			return $response;
338
+		}
339
+		if (! isset($response['id'])) {
340
+			$message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso');
341
+			try {
342
+				PayPalLogger::errorLog(
343
+					$message,
344
+					[$this->request_url, $parameters, $response],
345
+					$this->transaction->payment_method()
346
+				);
347
+			} catch (EE_Error | ReflectionException $e) {
348
+				error_log("PayPalLogger Error: $message: " . json_encode($response));
349
+			}
350
+			return [
351
+				'error'    => $response['error'] ?? 'missing_order',
352
+				'message'  => $response['message'] ?? $message,
353
+				'response' => $response,
354
+			];
355
+		}
356
+		return $response;
357
+	}
358
+
359
+
360
+	/**
361
+	 * Check if PayPals response contains 'MISMATCH' errors.
362
+	 *
363
+	 * @return bool
364
+	 */
365
+	public function isMismatchError($response): bool
366
+	{
367
+		if (! isset($response['details']) || ! is_array($response['details'])) {
368
+			return false;
369
+		}
370
+
371
+		foreach($response['details'] as $detail) {
372
+			if (! empty($detail['issue'])) {
373
+				if (
374
+					strtoupper($detail['issue']) === 'ITEM_TOTAL_MISMATCH'
375
+					|| strtoupper($detail['issue']) === 'AMOUNT_MISMATCH'
376
+			) {
377
+					PayPalLogger::errorLog(
378
+						esc_html__('Mistmatch Error:', 'event_espresso'),
379
+						[$this->request_url, $response],
380
+						$this->transaction->payment_method(),
381
+						false,
382
+						$this->transaction
383
+					);
384
+					return true;
385
+				}
386
+			}
387
+		}
388
+		return false;
389
+	}
390
+
391
+
392
+	/**
393
+	 * Itemize the simplified payment breakdown list.
394
+	 *
395
+	 * @return array
396
+	 */
397
+	protected function getSimplifiedAmountBreakdown(): array
398
+	{
399
+		$tax_total = $this->transaction->tax_total();
400
+		$breakdown['item_total'] = [
401
+			'currency_code' => $this->currency_code,
402
+			'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining() - $tax_total)
403
+		];
404
+		if ($tax_total > 0) {
405
+			$breakdown['tax_total'] = [
406
+				'currency_code' => $this->currency_code,
407
+				'value'         => (string) CurrencyManager::normalizeValue($tax_total)
408
+			];
409
+		}
410
+		return $breakdown;
411
+	}
412
+
413
+
414
+	/**
415
+	 * Generate single line item for full order.
416
+	 *
417
+	 * @return array
418
+	 */
419
+	protected function getSimplifiedItems(): array
420
+	{
421
+		// Simplified single line item.
422
+		$line_items             = [];
423
+		$primary_registrant     = $this->transaction->primary_registration();
424
+		$event_obj              = $primary_registrant->event_obj();
425
+		$name_and_description   = $this->gateway_data_formatter->formatOrderDescription($this->payment);
426 426
         
427
-        $line_items[]   = [
428
-            'name'        => substr(wp_strip_all_tags($name_and_description), 0, 125),
429
-            'quantity'    => 1,
430
-            'description' => substr(wp_strip_all_tags($name_and_description), 0, 2047),
431
-            'unit_amount' => [
432
-                'currency_code' => $this->currency_code,
433
-                'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining() - $this->transaction->tax_total()),
434
-            ],
435
-            'category'    => 'DIGITAL_GOODS',
436
-        ];
437
-        return $line_items;
438
-    }
439
-
440
-    /**
441
-     * Generates an EE_Payment object but doesn't save it.
442
-     */
443
-    private function setPaymentPlaceholder(): void
444
-    {
445
-        $this->payment = EE_Payment::new_instance(
446
-            [
447
-                'STS_ID'        => EEM_Payment::status_id_pending,
448
-                'TXN_ID'        => $this->transaction->ID(),
449
-                'PMD_ID'        => $this->transaction->payment_method_ID(),
450
-                'PAY_amount'    => 0.00,
451
-                'PAY_timestamp' => time(),
452
-            ]
453
-        );
454
-    }
427
+		$line_items[]   = [
428
+			'name'        => substr(wp_strip_all_tags($name_and_description), 0, 125),
429
+			'quantity'    => 1,
430
+			'description' => substr(wp_strip_all_tags($name_and_description), 0, 2047),
431
+			'unit_amount' => [
432
+				'currency_code' => $this->currency_code,
433
+				'value'         => (string) CurrencyManager::normalizeValue($this->transaction->remaining() - $this->transaction->tax_total()),
434
+			],
435
+			'category'    => 'DIGITAL_GOODS',
436
+		];
437
+		return $line_items;
438
+	}
439
+
440
+	/**
441
+	 * Generates an EE_Payment object but doesn't save it.
442
+	 */
443
+	private function setPaymentPlaceholder(): void
444
+	{
445
+		$this->payment = EE_Payment::new_instance(
446
+			[
447
+				'STS_ID'        => EEM_Payment::status_id_pending,
448
+				'TXN_ID'        => $this->transaction->ID(),
449
+				'PMD_ID'        => $this->transaction->payment_method_ID(),
450
+				'PAY_amount'    => 0.00,
451
+				'PAY_timestamp' => time(),
452
+			]
453
+		);
454
+	}
455 455
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
     {
112 112
         $sanitizer = new RequestSanitizer(new Basic());
113 113
         foreach ($billing_info as $item => $value) {
114
-            $this->billing_info[ $item ] = $sanitizer->clean($value);
114
+            $this->billing_info[$item] = $sanitizer->clean($value);
115 115
         }
116 116
     }
117 117
 
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
         ];
185 185
 
186 186
         // If we have and address on the attendee, send it to PayPal.
187
-        if($attendee->country_ID()) {
187
+        if ($attendee->country_ID()) {
188 188
             $parameters['payment_source']['paypal']['address'] = [
189 189
                 'address_line_1'    => $attendee->address(),
190 190
                 'address_line_2'    => $attendee->address2(),
@@ -203,7 +203,7 @@  discard block
 block discarded – undo
203 203
         if (
204 204
             (
205 205
                 (defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES)
206
-                || (! defined('EE_PPC_USE_PAYMENT_FEES')
206
+                || ( ! defined('EE_PPC_USE_PAYMENT_FEES')
207 207
                     && $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES)
208 208
                 )
209 209
             )
@@ -303,11 +303,11 @@  discard block
 block discarded – undo
303 303
             'currency_code' => $this->currency_code,
304 304
             'value'         => (string) $this->items_total,
305 305
         ];
306
-        $breakdown['tax_total']  = [
306
+        $breakdown['tax_total'] = [
307 307
             'currency_code' => $this->currency_code,
308 308
             'value'         => (string) $this->tax_total,
309 309
         ];
310
-        $breakdown['discount']   = [
310
+        $breakdown['discount'] = [
311 311
             'currency_code' => $this->currency_code,
312 312
             'value'         => (string) abs($this->promos_total),
313 313
         ];
@@ -333,10 +333,10 @@  discard block
 block discarded – undo
333 333
             false,
334 334
             $this->transaction
335 335
         );
336
-        if (! empty($response['error'])) {
336
+        if ( ! empty($response['error'])) {
337 337
             return $response;
338 338
         }
339
-        if (! isset($response['id'])) {
339
+        if ( ! isset($response['id'])) {
340 340
             $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso');
341 341
             try {
342 342
                 PayPalLogger::errorLog(
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
                     $this->transaction->payment_method()
346 346
                 );
347 347
             } catch (EE_Error | ReflectionException $e) {
348
-                error_log("PayPalLogger Error: $message: " . json_encode($response));
348
+                error_log("PayPalLogger Error: $message: ".json_encode($response));
349 349
             }
350 350
             return [
351 351
                 'error'    => $response['error'] ?? 'missing_order',
@@ -364,12 +364,12 @@  discard block
 block discarded – undo
364 364
      */
365 365
     public function isMismatchError($response): bool
366 366
     {
367
-        if (! isset($response['details']) || ! is_array($response['details'])) {
367
+        if ( ! isset($response['details']) || ! is_array($response['details'])) {
368 368
             return false;
369 369
         }
370 370
 
371
-        foreach($response['details'] as $detail) {
372
-            if (! empty($detail['issue'])) {
371
+        foreach ($response['details'] as $detail) {
372
+            if ( ! empty($detail['issue'])) {
373 373
                 if (
374 374
                     strtoupper($detail['issue']) === 'ITEM_TOTAL_MISMATCH'
375 375
                     || strtoupper($detail['issue']) === 'AMOUNT_MISMATCH'
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
         $event_obj              = $primary_registrant->event_obj();
425 425
         $name_and_description   = $this->gateway_data_formatter->formatOrderDescription($this->payment);
426 426
         
427
-        $line_items[]   = [
427
+        $line_items[] = [
428 428
             'name'        => substr(wp_strip_all_tags($name_and_description), 0, 125),
429 429
             'quantity'    => 1,
430 430
             'description' => substr(wp_strip_all_tags($name_and_description), 0, 2047),
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -37,138 +37,138 @@
 block discarded – undo
37 37
  * @since       4.0
38 38
  */
39 39
 if (function_exists('espresso_version')) {
40
-    if (! function_exists('espresso_duplicate_plugin_error')) {
41
-        /**
42
-         *    espresso_duplicate_plugin_error
43
-         *    displays if more than one version of EE is activated at the same time.
44
-         */
45
-        function espresso_duplicate_plugin_error()
46
-        {
47
-            ?>
40
+	if (! function_exists('espresso_duplicate_plugin_error')) {
41
+		/**
42
+		 *    espresso_duplicate_plugin_error
43
+		 *    displays if more than one version of EE is activated at the same time.
44
+		 */
45
+		function espresso_duplicate_plugin_error()
46
+		{
47
+			?>
48 48
 <div class="error">
49 49
     <p>
50 50
         <?php
51
-                    echo esc_html__(
52
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
-                        'event_espresso'
54
-                    ); ?>
51
+					echo esc_html__(
52
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
+						'event_espresso'
54
+					); ?>
55 55
     </p>
56 56
 </div>
57 57
 <?php
58
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
59
-        }
60
-    }
61
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
58
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
59
+		}
60
+	}
61
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62 62
 } else {
63
-    define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
-        /**
66
-         * espresso_minimum_php_version_error
67
-         *
68
-         * @return void
69
-         */
70
-        function espresso_minimum_php_version_error()
71
-        {
72
-            ?>
63
+	define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
+		/**
66
+		 * espresso_minimum_php_version_error
67
+		 *
68
+		 * @return void
69
+		 */
70
+		function espresso_minimum_php_version_error()
71
+		{
72
+			?>
73 73
 <div class="error">
74 74
     <p>
75 75
         <?php
76
-                    printf(
77
-                        esc_html__(
78
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
-                            'event_espresso'
80
-                        ),
81
-                        EE_MIN_PHP_VER_REQUIRED,
82
-                        PHP_VERSION,
83
-                        '<br/>',
84
-                        '<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
-                    );
86
-        ?>
76
+					printf(
77
+						esc_html__(
78
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
+							'event_espresso'
80
+						),
81
+						EE_MIN_PHP_VER_REQUIRED,
82
+						PHP_VERSION,
83
+						'<br/>',
84
+						'<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
+					);
86
+		?>
87 87
     </p>
88 88
 </div>
89 89
 <?php
90
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
91
-        }
90
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
91
+		}
92 92
 
93
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
-    } else {
95
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
93
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
+	} else {
95
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
96 96
 
97
-        require_once __DIR__ . '/vendor/autoload.php';
97
+		require_once __DIR__ . '/vendor/autoload.php';
98 98
 
99
-        /**
100
-         * espresso_version
101
-         * Returns the plugin version
102
-         *
103
-         * @return string
104
-         */
105
-        function espresso_version(): string
106
-        {
107
-            return apply_filters('FHEE__espresso__espresso_version', '5.0.44');
108
-        }
99
+		/**
100
+		 * espresso_version
101
+		 * Returns the plugin version
102
+		 *
103
+		 * @return string
104
+		 */
105
+		function espresso_version(): string
106
+		{
107
+			return apply_filters('FHEE__espresso__espresso_version', '5.0.44');
108
+		}
109 109
 
110
-        /**
111
-         * espresso_plugin_activation
112
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
-         */
114
-        function espresso_plugin_activation()
115
-        {
116
-            update_option('ee_espresso_activation', true);
117
-            update_option('event-espresso-core_allow_tracking', 'no');
118
-            update_option('event-espresso-core_tracking_notice', 'hide');
119
-            // Run WP GraphQL activation callback
120
-            espressoLoadWpGraphQL();
121
-            graphql_activation_callback();
122
-        }
110
+		/**
111
+		 * espresso_plugin_activation
112
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
+		 */
114
+		function espresso_plugin_activation()
115
+		{
116
+			update_option('ee_espresso_activation', true);
117
+			update_option('event-espresso-core_allow_tracking', 'no');
118
+			update_option('event-espresso-core_tracking_notice', 'hide');
119
+			// Run WP GraphQL activation callback
120
+			espressoLoadWpGraphQL();
121
+			graphql_activation_callback();
122
+		}
123 123
 
124
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
124
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
125 125
 
126
-        /**
127
-         * espresso_plugin_deactivation
128
-         */
129
-        function espresso_plugin_deactivation()
130
-        {
131
-            // Run WP GraphQL deactivation callback
132
-            espressoLoadWpGraphQL();
133
-            graphql_deactivation_callback();
134
-            delete_option('event-espresso-core_allow_tracking');
135
-            delete_option('event-espresso-core_tracking_notice');
136
-        }
137
-        register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
126
+		/**
127
+		 * espresso_plugin_deactivation
128
+		 */
129
+		function espresso_plugin_deactivation()
130
+		{
131
+			// Run WP GraphQL deactivation callback
132
+			espressoLoadWpGraphQL();
133
+			graphql_deactivation_callback();
134
+			delete_option('event-espresso-core_allow_tracking');
135
+			delete_option('event-espresso-core_tracking_notice');
136
+		}
137
+		register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
138 138
 
139
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
140
-        bootstrap_espresso();
141
-    }
139
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
140
+		bootstrap_espresso();
141
+	}
142 142
 }
143 143
 
144 144
 if (! function_exists('espresso_deactivate_plugin')) {
145
-    /**
146
-     *    deactivate_plugin
147
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
-     *
149
-     * @access public
150
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
-     * @return    void
152
-     */
153
-    function espresso_deactivate_plugin(string $plugin_basename = '')
154
-    {
155
-        if (! function_exists('deactivate_plugins')) {
156
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
-        }
158
-        unset($_GET['activate'], $_REQUEST['activate']);
159
-        deactivate_plugins($plugin_basename);
160
-    }
145
+	/**
146
+	 *    deactivate_plugin
147
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
+	 *
149
+	 * @access public
150
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
+	 * @return    void
152
+	 */
153
+	function espresso_deactivate_plugin(string $plugin_basename = '')
154
+	{
155
+		if (! function_exists('deactivate_plugins')) {
156
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
+		}
158
+		unset($_GET['activate'], $_REQUEST['activate']);
159
+		deactivate_plugins($plugin_basename);
160
+	}
161 161
 }
162 162
 
163 163
 
164 164
 if (! function_exists('espressoLoadWpGraphQL')) {
165
-    function espressoLoadWpGraphQL()
166
-    {
167
-        if (
168
-            ! class_exists('WPGraphQL')
169
-            && is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
-        ) {
171
-            require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
-        }
173
-    }
165
+	function espressoLoadWpGraphQL()
166
+	{
167
+		if (
168
+			! class_exists('WPGraphQL')
169
+			&& is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
+		) {
171
+			require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
+		}
173
+	}
174 174
 }
Please login to merge, or discard this patch.