← All changes
|
src/PaymentGateways/PayPalCommerce/AjaxRequestHandler.php
+17
-102
4.16.8
→
4.17.0
View file →
| @@ -6,9 +6,8 @@ | ||
| 6 | 6 | use Give\DonationForms\Exceptions\DonationFormFieldErrorsException; |
| 7 | 7 | use Give\DonationForms\Exceptions\DonationFormForbidden; |
| 8 | 8 | use Give\Log\Log; |
| 9 | 9 | use Give\PaymentGateways\PayPalCommerce\Models\MerchantDetail; |
| 10 | -use Give\PaymentGateways\PayPalCommerce\PayPalCheckoutSdk\ProcessorResponseError; | |
| 11 | 10 | use Give\PaymentGateways\PayPalCommerce\Repositories\MerchantDetails; |
| 12 | 11 | use Give\PaymentGateways\PayPalCommerce\Repositories\PayPalAuth; |
| 13 | 12 | use Give\PaymentGateways\PayPalCommerce\Repositories\PayPalOrder; |
| 14 | 13 | use Give\PaymentGateways\PayPalCommerce\Repositories\Settings; |
| @@ -328,12 +327,14 @@ | ||
| 328 | 327 | ]; |
| 329 | 328 | } |
| 330 | 329 | |
| 331 | 330 | /** |
| 332 | - * Approve order. | |
| 331 | + * Refuses every request. Both form versions now send their order id with the donation and let | |
| 332 | + * PayPalCommerce::createPayment() capture it, so nothing legitimate captures from the browser. | |
| 333 | + * The endpoint stays registered so anything still calling it receives an error it can report, | |
| 334 | + * rather than an empty response from a missing action. | |
| 333 | 335 | * |
| 334 | - * @todo: handle payment capture error on frontend. | |
| 335 | - * | |
| 336 | + * @since 4.16.9 Refuse every request; the capture for both form versions happens in PayPalCommerce::createPayment(). | |
| 336 | 337 | * @since 4.16.7.1 Refuse v3 forms; their capture happens in PayPalCommerce::createPayment(). Validate |
| 337 | 338 | * the posted form before every capture, not only when the amount changed. |
| 338 | 339 | * @since 4.14.4 Validate donation amount before approving an order. |
| 339 | 340 | * @since 3.2.0 Discover error by checking capture status. |
| @@ -340,33 +341,20 @@ | ||
| 340 | 341 | * @since 2.9.0 |
| 341 | 342 | */ |
| 342 | 343 | public function approveOrder() |
| 343 | 344 | { |
| 344 | - $this->validateFrontendRequest(); | |
| 345 | - $this->rejectV3FormRequest(); | |
| 346 | - | |
| 347 | - $orderId = give_clean($_GET['order']); | |
| 348 | - $updateAmount = filter_var(give_clean($_GET['update_amount']), FILTER_VALIDATE_BOOLEAN); | |
| 349 | - | |
| 350 | - try { | |
| 351 | - $orderData = $this->getOrderData(); | |
| 352 | - | |
| 353 | - if ($updateAmount) { | |
| 354 | - $this->validateOrderAmountNotDecreased($orderId, $orderData['donationAmount']); | |
| 355 | - give(PayPalOrder::class)->updateOrderAmount($orderId, $orderData); | |
| 356 | - } | |
| 357 | - | |
| 358 | - $result = give(PayPalOrder::class)->approveOrder($orderId); | |
| 359 | - // PayPal does not return error in case of invalid cvv. So we need to check capture status and return error. | |
| 360 | - // ref - https://feedback.givewp.com/bug-reports/p/paypal-credit-card-donations-can-generate-a-fatal-error | |
| 361 | - $this->returnErrorOnFailedApproveOrderResponse($result); | |
| 362 | - wp_send_json_success(['order' => $result,]); | |
| 363 | - } catch (\Exception $ex) { | |
| 364 | - wp_send_json_error(['error' => json_decode($ex->getMessage(), true),]); | |
| 365 | - } | |
| 345 | + wp_send_json_error( | |
| 346 | + ['error' => __('PayPal orders are captured when the donation is submitted.', 'give')] | |
| 347 | + ); | |
| 366 | 348 | } |
| 367 | 349 | |
| 368 | 350 | /** |
| 351 | + * Refuses every request. The order amount is reconciled against the donation in | |
| 352 | + * PayPalCommerce::createPayment() before the capture, so no form version needs the browser to | |
| 353 | + * change an order's amount. The endpoint stays registered for the same reason approveOrder() | |
| 354 | + * does: a caller gets an error it can report rather than an empty response. | |
| 355 | + * | |
| 356 | + * @since 4.16.9 Refuse every request; the order amount is reconciled in PayPalCommerce::createPayment(). | |
| 369 | 357 | * @since 4.16.7.1 Refuse v3 forms; PayPalCommerce::createPayment() reconciles their order amount. |
| 370 | 358 | * @since 4.14.4 Validate donation amount before updating an order amount. |
| 371 | 359 | * @since 3.4.2 |
| 372 | 360 | */ |
| @@ -371,22 +359,11 @@ | ||
| 371 | 359 | * @since 3.4.2 |
| 372 | 360 | */ |
| 373 | 361 | public function updateOrderAmount() |
| 374 | 362 | { |
| 375 | - $this->validateFrontendRequest(); | |
| 376 | - $this->rejectV3FormRequest(); | |
| 377 | - | |
| 378 | - $orderId = give_clean($_GET['order']); | |
| 379 | - | |
| 380 | - try { | |
| 381 | - $orderData = $this->getOrderData(); | |
| 382 | - $this->validateOrderAmountNotDecreased($orderId, $orderData['donationAmount']); | |
| 383 | - give(PayPalOrder::class)->updateOrderAmount($orderId, $orderData); | |
| 384 | - | |
| 385 | - wp_send_json_success(['order' => $orderId,]); | |
| 386 | - } catch (\Exception $ex) { | |
| 387 | - wp_send_json_error(['error' => json_decode($ex->getMessage(), true),]); | |
| 388 | - } | |
| 363 | + wp_send_json_error( | |
| 364 | + ['error' => __('PayPal order amounts are reconciled when the donation is submitted.', 'give')] | |
| 365 | + ); | |
| 389 | 366 | } |
| 390 | 367 | |
| 391 | 368 | /** |
| 392 | 369 | * Return on boarding trouble notice. |
| @@ -530,47 +507,8 @@ | ||
| 530 | 507 | } |
| 531 | 508 | } |
| 532 | 509 | |
| 533 | 510 | /** |
| 534 | - * Visual Form Builder (v3) forms never call the approve and update-amount endpoints: their order | |
| 535 | - * is reconciled and captured in PayPalCommerce::createPayment(), after the donation exists. | |
| 536 | - * Refusing them here keeps these endpoints from capturing outside donation processing. | |
| 537 | - * | |
| 538 | - * @since 4.16.7.1 | |
| 539 | - */ | |
| 540 | - private function rejectV3FormRequest(): void | |
| 541 | - { | |
| 542 | - if (FormUtils::isV3Form(absint($_POST['give-form-id']))) { | |
| 543 | - wp_send_json_error( | |
| 544 | - ['error' => __('This request is not supported for this donation form.', 'give')], | |
| 545 | - 403 | |
| 546 | - ); | |
| 547 | - } | |
| 548 | - } | |
| 549 | - | |
| 550 | - /** | |
| 551 | - * Validate that the new donation amount is not less than the original PayPal order amount. | |
| 552 | - * | |
| 553 | - * @since 4.14.4 | |
| 554 | - * | |
| 555 | - * @param string $orderId | |
| 556 | - * @param float|string $newAmount | |
| 557 | - */ | |
| 558 | - private function validateOrderAmountNotDecreased(string $orderId, $newAmount): void | |
| 559 | - { | |
| 560 | - $newAmount = (float)$newAmount; | |
| 561 | - | |
| 562 | - $currentOrder = give(PayPalOrder::class)->getApprovedOrder($orderId); | |
| 563 | - $currentAmount = (float)$currentOrder->purchase_units[0]->amount->value; | |
| 564 | - | |
| 565 | - if ($newAmount < $currentAmount) { | |
| 566 | - wp_send_json_error([ | |
| 567 | - 'error' => __('Donation amount cannot be decreased.', 'give'), | |
| 568 | - ]); | |
| 569 | - } | |
| 570 | - } | |
| 571 | - | |
| 572 | - /** | |
| 573 | 511 | * This function should return address array in PayPal rest api accepted format. |
| 574 | 512 | * |
| 575 | 513 | * @since 3.1.0 Return address only if setting enabled and has valida country in PayPal accepted formatted. |
| 576 | 514 | * @since 2.11.1 |
| @@ -590,28 +528,5 @@ | ||
| 590 | 528 | |
| 591 | 529 | return $address; |
| 592 | 530 | } |
| 593 | 531 | |
| 594 | - /** | |
| 595 | - * This function should validate PayPal ApproveOrder response and respond to ajax request on error. | |
| 596 | - * | |
| 597 | - * @since 3.2.0 | |
| 598 | - */ | |
| 599 | - private function returnErrorOnFailedApproveOrderResponse(\stdClass $response) | |
| 600 | - { | |
| 601 | - // Get capture. | |
| 602 | - // ref - https://developer.paypal.com/docs/api/orders/v2/#orders_capture | |
| 603 | - $capture = $response->purchase_units[0]->payments->captures[0]; | |
| 604 | - | |
| 605 | - // Check if capture status is failed or declined. | |
| 606 | - if ( | |
| 607 | - in_array($capture->status, ['FAILED', 'DECLINED']) | |
| 608 | - && property_exists($capture, 'processor_response') | |
| 609 | - ) { | |
| 610 | - $error = ProcessorResponseError::getError($capture->processor_response); | |
| 611 | - | |
| 612 | - if ($error) { | |
| 613 | - wp_send_json_error(['error' => $error]); | |
| 614 | - } | |
| 615 | - } | |
| 616 | - } | |
| 617 | 532 | } |