-
Notifications
You must be signed in to change notification settings - Fork 70
Expand file tree
/
Copy pathPaymentsStatusHandlingTrait.php
More file actions
175 lines (159 loc) · 5.35 KB
/
Copy pathPaymentsStatusHandlingTrait.php
File metadata and controls
175 lines (159 loc) · 5.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?php
/**
* Common operations performed after payment authorization/capture.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Processor
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
use WC_Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
use WooCommerce\PayPalCommerce\ApiClient\Entity\CaptureStatus;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
/**
* Trait PaymentsStatusHandlingTrait.
*/
trait PaymentsStatusHandlingTrait {
/**
* Changes status of a newly created order, based on the capture/authorization.
*
* @param Order $order The PayPal order.
* @param WC_Order $wc_order The WC order.
*
* @throws RuntimeException If payment denied.
*/
protected function handle_new_order_status(
Order $order,
WC_Order $wc_order
): void {
if ( $order->intent() === 'CAPTURE' ) {
$purchase_units = $order->purchase_units();
if ( ! empty( $purchase_units ) && isset( $purchase_units[0] ) ) {
$payments = $purchase_units[0]->payments();
if ( $payments && ! empty( $payments->captures() ) ) {
$this->handle_capture_status( $payments->captures()[0], $wc_order );
}
}
} elseif ( $order->intent() === 'AUTHORIZE' ) {
$purchase_units = $order->purchase_units();
if ( ! empty( $purchase_units ) && isset( $purchase_units[0] ) ) {
$payments = $purchase_units[0]->payments();
if ( $payments && ! empty( $payments->authorizations() ) ) {
$this->handle_authorization_status( $payments->authorizations()[0], $wc_order );
}
}
}
}
/**
* Changes the order status, based on the capture.
*
* @param Capture $capture The capture.
* @param WC_Order $wc_order The WC order.
*
* @throws RuntimeException If payment denied.
*/
protected function handle_capture_status(
Capture $capture,
WC_Order $wc_order
): void {
$status = $capture->status();
$details = $status->details();
if ( $details ) {
$this->add_status_details_note( $wc_order, $status->name(), $details->text() );
}
switch ( $status->name() ) {
case CaptureStatus::COMPLETED:
$wc_order->payment_complete();
/**
* Fired when PayPal order is captured.
*/
do_action( 'woocommerce_paypal_payments_order_captured', $wc_order, $capture );
break;
// It is checked in the capture endpoint already, but there are other ways to capture,
// such as when paid via saved card.
case CaptureStatus::DECLINED:
$fraud = $capture->fraud_processor_response();
$status_note = ( $fraud && $fraud->response_code() )
? sprintf(
/* translators: %s - processor response code and description */
__( 'Could not capture the payment. Processor response: %s', 'woocommerce-paypal-payments' ),
$fraud->get_response_code_message()
)
: __( 'Could not capture the payment.', 'woocommerce-paypal-payments' );
$wc_order->update_status( 'failed', $status_note );
$decline_message = $fraud
? $fraud->get_customer_decline_message()
: __( 'Payment provider declined the payment, please use a different payment method.', 'woocommerce-paypal-payments' );
throw new RuntimeException( $decline_message );
case CaptureStatus::PENDING:
case CaptureStatus::FAILED:
$wc_order->update_status(
'on-hold',
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
);
break;
}
}
/**
* Changes the order status, based on the authorization.
*
* @param Authorization $authorization The authorization.
* @param WC_Order $wc_order The WC order.
*
* @throws RuntimeException If payment denied.
*/
protected function handle_authorization_status(
Authorization $authorization,
WC_Order $wc_order
): void {
$status = $authorization->status();
$details = $status->details();
if ( $details ) {
$this->add_status_details_note( $wc_order, $status->name(), $details->text() );
}
switch ( $status->name() ) {
case AuthorizationStatus::CREATED:
case AuthorizationStatus::PENDING:
$wc_order->update_status(
'on-hold',
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
);
/**
* Fired when PayPal order is authorized.
*/
do_action( 'woocommerce_paypal_payments_order_authorized', $wc_order, $authorization );
break;
case AuthorizationStatus::DENIED:
$wc_order->update_status(
'failed',
__( 'Could not get the payment authorization.', 'woocommerce-paypal-payments' )
);
throw new RuntimeException( __( 'Payment provider declined the payment, please use a different payment method.', 'woocommerce-paypal-payments' ) );
}
}
/**
* Adds the order note with status details.
*
* @param WC_Order $wc_order The WC order to which the note will be added.
* @param string $status The status name.
* @param string $reason The status reason.
*/
protected function add_status_details_note(
WC_Order $wc_order,
string $status,
string $reason
): void {
$wc_order->add_order_note(
sprintf(
/* translators: %1$s - PENDING, DENIED, ... %2$s - text explaining the reason, ... */
__( 'PayPal order payment is set to %1$s status, details: %2$s', 'woocommerce-paypal-payments' ),
$status,
$reason
)
);
$wc_order->save();
}
}