@@ -23,258 +23,258 @@ |
||
23 | 23 | */ |
24 | 24 | class CreateOrder extends OrdersApi |
25 | 25 | { |
26 | - /** |
|
27 | - * Line items total. |
|
28 | - * |
|
29 | - * @var float |
|
30 | - */ |
|
31 | - protected $items_total = 0; |
|
26 | + /** |
|
27 | + * Line items total. |
|
28 | + * |
|
29 | + * @var float |
|
30 | + */ |
|
31 | + protected $items_total = 0; |
|
32 | 32 | |
33 | - /** |
|
34 | - * Promotions total. |
|
35 | - * |
|
36 | - * @var float |
|
37 | - */ |
|
38 | - protected $promos_total = 0; |
|
33 | + /** |
|
34 | + * Promotions total. |
|
35 | + * |
|
36 | + * @var float |
|
37 | + */ |
|
38 | + protected $promos_total = 0; |
|
39 | 39 | |
40 | - /** |
|
41 | - * Tax total. |
|
42 | - * |
|
43 | - * @var float |
|
44 | - */ |
|
45 | - protected $tax_total = 0; |
|
40 | + /** |
|
41 | + * Tax total. |
|
42 | + * |
|
43 | + * @var float |
|
44 | + */ |
|
45 | + protected $tax_total = 0; |
|
46 | 46 | |
47 | - /** |
|
48 | - * Currency. |
|
49 | - * |
|
50 | - * @var string |
|
51 | - */ |
|
52 | - protected string $currency_code; |
|
47 | + /** |
|
48 | + * Currency. |
|
49 | + * |
|
50 | + * @var string |
|
51 | + */ |
|
52 | + protected string $currency_code; |
|
53 | 53 | |
54 | - /** |
|
55 | - * Billing info. |
|
56 | - * |
|
57 | - * @var array |
|
58 | - */ |
|
59 | - protected array $billing_info; |
|
54 | + /** |
|
55 | + * Billing info. |
|
56 | + * |
|
57 | + * @var array |
|
58 | + */ |
|
59 | + protected array $billing_info; |
|
60 | 60 | |
61 | - /** |
|
62 | - * Transaction this order is for. |
|
63 | - * |
|
64 | - * @var EE_Transaction |
|
65 | - */ |
|
66 | - protected EE_Transaction $transaction; |
|
61 | + /** |
|
62 | + * Transaction this order is for. |
|
63 | + * |
|
64 | + * @var EE_Transaction |
|
65 | + */ |
|
66 | + protected EE_Transaction $transaction; |
|
67 | 67 | |
68 | 68 | |
69 | - /** |
|
70 | - * CreateOrder constructor. |
|
71 | - * |
|
72 | - * @param PayPalApi $api |
|
73 | - * @param EE_Transaction $transaction |
|
74 | - * @param array $billing_info |
|
75 | - */ |
|
76 | - public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info) |
|
77 | - { |
|
78 | - parent::__construct($api); |
|
79 | - $this->transaction = $transaction; |
|
80 | - $this->currency_code = CurrencyManager::currencyCode(); |
|
81 | - $this->sanitizeRequestParameters($billing_info); |
|
82 | - } |
|
69 | + /** |
|
70 | + * CreateOrder constructor. |
|
71 | + * |
|
72 | + * @param PayPalApi $api |
|
73 | + * @param EE_Transaction $transaction |
|
74 | + * @param array $billing_info |
|
75 | + */ |
|
76 | + public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info) |
|
77 | + { |
|
78 | + parent::__construct($api); |
|
79 | + $this->transaction = $transaction; |
|
80 | + $this->currency_code = CurrencyManager::currencyCode(); |
|
81 | + $this->sanitizeRequestParameters($billing_info); |
|
82 | + } |
|
83 | 83 | |
84 | 84 | |
85 | - /** |
|
86 | - * Sanitize the array of billing form data. |
|
87 | - * |
|
88 | - * @param array $billing_info |
|
89 | - * @return void |
|
90 | - */ |
|
91 | - public function sanitizeRequestParameters(array $billing_info): void |
|
92 | - { |
|
93 | - $email_validator = new Basic(); |
|
94 | - $sanitizer = new RequestSanitizer($email_validator); |
|
95 | - foreach ($billing_info as $item => $value) |
|
96 | - { |
|
97 | - $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
98 | - } |
|
99 | - } |
|
85 | + /** |
|
86 | + * Sanitize the array of billing form data. |
|
87 | + * |
|
88 | + * @param array $billing_info |
|
89 | + * @return void |
|
90 | + */ |
|
91 | + public function sanitizeRequestParameters(array $billing_info): void |
|
92 | + { |
|
93 | + $email_validator = new Basic(); |
|
94 | + $sanitizer = new RequestSanitizer($email_validator); |
|
95 | + foreach ($billing_info as $item => $value) |
|
96 | + { |
|
97 | + $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
98 | + } |
|
99 | + } |
|
100 | 100 | |
101 | 101 | |
102 | - /** |
|
103 | - * Create PayPal Order. |
|
104 | - * |
|
105 | - * @return array |
|
106 | - * @throws EE_Error |
|
107 | - * @throws ReflectionException |
|
108 | - */ |
|
109 | - public function create(): array |
|
110 | - { |
|
111 | - $order_parameters = $this->getParameters(); |
|
112 | - // Create Order request. |
|
113 | - $create_response = $this->api->sendRequest($order_parameters, $this->request_url); |
|
114 | - return $this->validateOrder($create_response, $order_parameters); |
|
115 | - } |
|
102 | + /** |
|
103 | + * Create PayPal Order. |
|
104 | + * |
|
105 | + * @return array |
|
106 | + * @throws EE_Error |
|
107 | + * @throws ReflectionException |
|
108 | + */ |
|
109 | + public function create(): array |
|
110 | + { |
|
111 | + $order_parameters = $this->getParameters(); |
|
112 | + // Create Order request. |
|
113 | + $create_response = $this->api->sendRequest($order_parameters, $this->request_url); |
|
114 | + return $this->validateOrder($create_response, $order_parameters); |
|
115 | + } |
|
116 | 116 | |
117 | 117 | |
118 | - /** |
|
119 | - * Form order parameters. |
|
120 | - * |
|
121 | - * @return array |
|
122 | - * @throws EE_Error |
|
123 | - * @throws ReflectionException |
|
124 | - */ |
|
125 | - protected function getParameters(): array |
|
126 | - { |
|
127 | - $registrant = $this->transaction->primary_registration(); |
|
128 | - $attendee = $registrant->attendee(); |
|
129 | - $event = $registrant->event(); |
|
130 | - $description = $event->name() ?: sprintf( |
|
131 | - esc_html__('Tickets for an event at %1$s', 'event_espresso'), |
|
132 | - get_bloginfo('name') |
|
133 | - ); |
|
134 | - return [ |
|
135 | - 'intent' => 'CAPTURE', |
|
136 | - 'purchase_units' => [ |
|
137 | - [ |
|
138 | - 'custom_id' => $this->transaction->ID(), |
|
139 | - 'description' => substr(wp_strip_all_tags($description), 0, 125), |
|
140 | - 'items' => $this->getLineItems(), |
|
141 | - 'amount' => [ |
|
142 | - 'value' => $this->transaction->total(), |
|
143 | - 'currency_code' => $this->currency_code, |
|
144 | - 'breakdown' => $this->getBreakdown(), |
|
145 | - ], |
|
146 | - ], |
|
147 | - ], |
|
148 | - 'application_context' => [ |
|
149 | - 'shipping_preference' => 'NO_SHIPPING', |
|
150 | - 'user_action' => 'PAY_NOW', |
|
151 | - ], |
|
152 | - 'payer' => [ |
|
153 | - 'email_address' => $attendee->email(), |
|
154 | - 'name' => [ |
|
155 | - 'given_name' => $attendee->fname(), |
|
156 | - 'surname' => $attendee->lname(), |
|
118 | + /** |
|
119 | + * Form order parameters. |
|
120 | + * |
|
121 | + * @return array |
|
122 | + * @throws EE_Error |
|
123 | + * @throws ReflectionException |
|
124 | + */ |
|
125 | + protected function getParameters(): array |
|
126 | + { |
|
127 | + $registrant = $this->transaction->primary_registration(); |
|
128 | + $attendee = $registrant->attendee(); |
|
129 | + $event = $registrant->event(); |
|
130 | + $description = $event->name() ?: sprintf( |
|
131 | + esc_html__('Tickets for an event at %1$s', 'event_espresso'), |
|
132 | + get_bloginfo('name') |
|
133 | + ); |
|
134 | + return [ |
|
135 | + 'intent' => 'CAPTURE', |
|
136 | + 'purchase_units' => [ |
|
137 | + [ |
|
138 | + 'custom_id' => $this->transaction->ID(), |
|
139 | + 'description' => substr(wp_strip_all_tags($description), 0, 125), |
|
140 | + 'items' => $this->getLineItems(), |
|
141 | + 'amount' => [ |
|
142 | + 'value' => $this->transaction->total(), |
|
143 | + 'currency_code' => $this->currency_code, |
|
144 | + 'breakdown' => $this->getBreakdown(), |
|
145 | + ], |
|
146 | + ], |
|
147 | + ], |
|
148 | + 'application_context' => [ |
|
149 | + 'shipping_preference' => 'NO_SHIPPING', |
|
150 | + 'user_action' => 'PAY_NOW', |
|
151 | + ], |
|
152 | + 'payer' => [ |
|
153 | + 'email_address' => $attendee->email(), |
|
154 | + 'name' => [ |
|
155 | + 'given_name' => $attendee->fname(), |
|
156 | + 'surname' => $attendee->lname(), |
|
157 | 157 | |
158 | - ], |
|
159 | - ], |
|
160 | - ]; |
|
161 | - } |
|
158 | + ], |
|
159 | + ], |
|
160 | + ]; |
|
161 | + } |
|
162 | 162 | |
163 | 163 | |
164 | - /** |
|
165 | - * Itemize the payment. List all the line items, discounts and taxes. |
|
166 | - * |
|
167 | - * @return array |
|
168 | - * @throws EE_Error|ReflectionException |
|
169 | - */ |
|
170 | - protected function getLineItems(): array |
|
171 | - { |
|
172 | - // Order line items. |
|
173 | - $line_items = []; |
|
174 | - $event_line_items = $this->transaction->items_purchased(); |
|
175 | - // List actual line items. |
|
176 | - foreach ($event_line_items as $line_item) { |
|
177 | - if ($line_item instanceof EE_Line_Item && $line_item->OBJ_type() !== 'Promotion') { |
|
178 | - $item_money = $line_item->unit_price(); |
|
179 | - $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); |
|
180 | - $line_items [] = [ |
|
181 | - 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126), |
|
182 | - 'quantity' => $line_item->quantity(), |
|
183 | - 'description' => substr(wp_strip_all_tags($li_description), 0, 125), |
|
184 | - 'unit_amount' => [ |
|
185 | - 'currency_code' => $this->currency_code, |
|
186 | - 'value' => $item_money, |
|
187 | - ], |
|
188 | - 'category' => 'DIGITAL_GOODS', |
|
189 | - ]; |
|
190 | - // Line item total. |
|
191 | - $this->items_total += $line_item->pretaxTotal(); |
|
192 | - } elseif ($line_item->OBJ_type() === 'Promotion') { |
|
193 | - // Promotions total. |
|
194 | - $this->promos_total += $line_item->total(); |
|
195 | - } |
|
196 | - } |
|
197 | - // Make sure we have an absolute number with only two decimal laces. |
|
198 | - $this->items_total = CurrencyManager::normalizeValue($this->items_total); |
|
199 | - $this->promos_total = CurrencyManager::normalizeValue($this->promos_total); |
|
200 | - $this->countTaxTotal(); |
|
201 | - return $line_items; |
|
202 | - } |
|
164 | + /** |
|
165 | + * Itemize the payment. List all the line items, discounts and taxes. |
|
166 | + * |
|
167 | + * @return array |
|
168 | + * @throws EE_Error|ReflectionException |
|
169 | + */ |
|
170 | + protected function getLineItems(): array |
|
171 | + { |
|
172 | + // Order line items. |
|
173 | + $line_items = []; |
|
174 | + $event_line_items = $this->transaction->items_purchased(); |
|
175 | + // List actual line items. |
|
176 | + foreach ($event_line_items as $line_item) { |
|
177 | + if ($line_item instanceof EE_Line_Item && $line_item->OBJ_type() !== 'Promotion') { |
|
178 | + $item_money = $line_item->unit_price(); |
|
179 | + $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); |
|
180 | + $line_items [] = [ |
|
181 | + 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126), |
|
182 | + 'quantity' => $line_item->quantity(), |
|
183 | + 'description' => substr(wp_strip_all_tags($li_description), 0, 125), |
|
184 | + 'unit_amount' => [ |
|
185 | + 'currency_code' => $this->currency_code, |
|
186 | + 'value' => $item_money, |
|
187 | + ], |
|
188 | + 'category' => 'DIGITAL_GOODS', |
|
189 | + ]; |
|
190 | + // Line item total. |
|
191 | + $this->items_total += $line_item->pretaxTotal(); |
|
192 | + } elseif ($line_item->OBJ_type() === 'Promotion') { |
|
193 | + // Promotions total. |
|
194 | + $this->promos_total += $line_item->total(); |
|
195 | + } |
|
196 | + } |
|
197 | + // Make sure we have an absolute number with only two decimal laces. |
|
198 | + $this->items_total = CurrencyManager::normalizeValue($this->items_total); |
|
199 | + $this->promos_total = CurrencyManager::normalizeValue($this->promos_total); |
|
200 | + $this->countTaxTotal(); |
|
201 | + return $line_items; |
|
202 | + } |
|
203 | 203 | |
204 | 204 | |
205 | - /** |
|
206 | - * Count the tax total. |
|
207 | - * |
|
208 | - * @return void |
|
209 | - * @throws EE_Error|ReflectionException |
|
210 | - */ |
|
211 | - protected function countTaxTotal(): void |
|
212 | - { |
|
213 | - // List taxes. |
|
214 | - $this->tax_total = 0; |
|
215 | - $tax_items = $this->transaction->tax_items(); |
|
216 | - foreach ($tax_items as $tax_item) { |
|
217 | - $this->tax_total += $tax_item->total(); |
|
218 | - } |
|
219 | - $this->tax_total = CurrencyManager::normalizeValue($this->tax_total); |
|
220 | - } |
|
205 | + /** |
|
206 | + * Count the tax total. |
|
207 | + * |
|
208 | + * @return void |
|
209 | + * @throws EE_Error|ReflectionException |
|
210 | + */ |
|
211 | + protected function countTaxTotal(): void |
|
212 | + { |
|
213 | + // List taxes. |
|
214 | + $this->tax_total = 0; |
|
215 | + $tax_items = $this->transaction->tax_items(); |
|
216 | + foreach ($tax_items as $tax_item) { |
|
217 | + $this->tax_total += $tax_item->total(); |
|
218 | + } |
|
219 | + $this->tax_total = CurrencyManager::normalizeValue($this->tax_total); |
|
220 | + } |
|
221 | 221 | |
222 | 222 | |
223 | - /** |
|
224 | - * Itemize the payment the breakdown list. |
|
225 | - * |
|
226 | - * @return array |
|
227 | - */ |
|
228 | - protected function getBreakdown(): array |
|
229 | - { |
|
230 | - $breakdown['item_total'] = [ |
|
231 | - 'currency_code' => $this->currency_code, |
|
232 | - 'value' => $this->items_total, |
|
233 | - ]; |
|
234 | - $breakdown['tax_total'] = [ |
|
235 | - 'currency_code' => $this->currency_code, |
|
236 | - 'value' => $this->tax_total, |
|
237 | - ]; |
|
238 | - $breakdown['discount'] = [ |
|
239 | - 'currency_code' => $this->currency_code, |
|
240 | - 'value' => abs($this->promos_total), |
|
241 | - ]; |
|
242 | - return $breakdown; |
|
243 | - } |
|
223 | + /** |
|
224 | + * Itemize the payment the breakdown list. |
|
225 | + * |
|
226 | + * @return array |
|
227 | + */ |
|
228 | + protected function getBreakdown(): array |
|
229 | + { |
|
230 | + $breakdown['item_total'] = [ |
|
231 | + 'currency_code' => $this->currency_code, |
|
232 | + 'value' => $this->items_total, |
|
233 | + ]; |
|
234 | + $breakdown['tax_total'] = [ |
|
235 | + 'currency_code' => $this->currency_code, |
|
236 | + 'value' => $this->tax_total, |
|
237 | + ]; |
|
238 | + $breakdown['discount'] = [ |
|
239 | + 'currency_code' => $this->currency_code, |
|
240 | + 'value' => abs($this->promos_total), |
|
241 | + ]; |
|
242 | + return $breakdown; |
|
243 | + } |
|
244 | 244 | |
245 | 245 | |
246 | - /** |
|
247 | - * Makes sure that we have received an Order back from the API call. |
|
248 | - * |
|
249 | - * @param $response |
|
250 | - * @param $parameters |
|
251 | - * @return array |
|
252 | - * @throws EE_Error |
|
253 | - * @throws ReflectionException |
|
254 | - */ |
|
255 | - public function validateOrder($response, $parameters): array |
|
256 | - { |
|
257 | - $message = esc_html__('Validating Order Create:', 'event_espresso'); |
|
258 | - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
259 | - if (! empty($response['error'])) { |
|
260 | - return $response; |
|
261 | - } |
|
262 | - if (! isset($response['id'])) { |
|
263 | - $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
|
264 | - try { |
|
265 | - PayPalLogger::errorLog( |
|
266 | - $message, |
|
267 | - [$this->request_url, $parameters, $response], |
|
268 | - $this->transaction->payment_method() |
|
269 | - ); |
|
270 | - } catch (EE_Error | ReflectionException $e) { |
|
271 | - // Just continue. |
|
272 | - } |
|
273 | - return [ |
|
274 | - 'error' => $response['error'] ?? 'missing_order', |
|
275 | - 'message' => $response['message'] ?? $message, |
|
276 | - ]; |
|
277 | - } |
|
278 | - return $response; |
|
279 | - } |
|
246 | + /** |
|
247 | + * Makes sure that we have received an Order back from the API call. |
|
248 | + * |
|
249 | + * @param $response |
|
250 | + * @param $parameters |
|
251 | + * @return array |
|
252 | + * @throws EE_Error |
|
253 | + * @throws ReflectionException |
|
254 | + */ |
|
255 | + public function validateOrder($response, $parameters): array |
|
256 | + { |
|
257 | + $message = esc_html__('Validating Order Create:', 'event_espresso'); |
|
258 | + PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
259 | + if (! empty($response['error'])) { |
|
260 | + return $response; |
|
261 | + } |
|
262 | + if (! isset($response['id'])) { |
|
263 | + $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
|
264 | + try { |
|
265 | + PayPalLogger::errorLog( |
|
266 | + $message, |
|
267 | + [$this->request_url, $parameters, $response], |
|
268 | + $this->transaction->payment_method() |
|
269 | + ); |
|
270 | + } catch (EE_Error | ReflectionException $e) { |
|
271 | + // Just continue. |
|
272 | + } |
|
273 | + return [ |
|
274 | + 'error' => $response['error'] ?? 'missing_order', |
|
275 | + 'message' => $response['message'] ?? $message, |
|
276 | + ]; |
|
277 | + } |
|
278 | + return $response; |
|
279 | + } |
|
280 | 280 | } |
@@ -94,7 +94,7 @@ discard block |
||
94 | 94 | $sanitizer = new RequestSanitizer($email_validator); |
95 | 95 | foreach ($billing_info as $item => $value) |
96 | 96 | { |
97 | - $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
97 | + $this->billing_info[$item] = $sanitizer->clean($value); |
|
98 | 98 | } |
99 | 99 | } |
100 | 100 | |
@@ -231,11 +231,11 @@ discard block |
||
231 | 231 | 'currency_code' => $this->currency_code, |
232 | 232 | 'value' => $this->items_total, |
233 | 233 | ]; |
234 | - $breakdown['tax_total'] = [ |
|
234 | + $breakdown['tax_total'] = [ |
|
235 | 235 | 'currency_code' => $this->currency_code, |
236 | 236 | 'value' => $this->tax_total, |
237 | 237 | ]; |
238 | - $breakdown['discount'] = [ |
|
238 | + $breakdown['discount'] = [ |
|
239 | 239 | 'currency_code' => $this->currency_code, |
240 | 240 | 'value' => abs($this->promos_total), |
241 | 241 | ]; |
@@ -256,10 +256,10 @@ discard block |
||
256 | 256 | { |
257 | 257 | $message = esc_html__('Validating Order Create:', 'event_espresso'); |
258 | 258 | PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
259 | - if (! empty($response['error'])) { |
|
259 | + if ( ! empty($response['error'])) { |
|
260 | 260 | return $response; |
261 | 261 | } |
262 | - if (! isset($response['id'])) { |
|
262 | + if ( ! isset($response['id'])) { |
|
263 | 263 | $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
264 | 264 | try { |
265 | 265 | PayPalLogger::errorLog( |
@@ -15,30 +15,30 @@ |
||
15 | 15 | */ |
16 | 16 | abstract class OrdersApi |
17 | 17 | { |
18 | - /** |
|
19 | - * @var PayPalApi |
|
20 | - */ |
|
21 | - protected PayPalApi $api; |
|
18 | + /** |
|
19 | + * @var PayPalApi |
|
20 | + */ |
|
21 | + protected PayPalApi $api; |
|
22 | 22 | |
23 | - /** |
|
24 | - * @var string |
|
25 | - */ |
|
26 | - protected string $request_url; |
|
23 | + /** |
|
24 | + * @var string |
|
25 | + */ |
|
26 | + protected string $request_url; |
|
27 | 27 | |
28 | - /** |
|
29 | - * @var string |
|
30 | - */ |
|
31 | - protected string $order_id; |
|
28 | + /** |
|
29 | + * @var string |
|
30 | + */ |
|
31 | + protected string $order_id; |
|
32 | 32 | |
33 | 33 | |
34 | - /** |
|
35 | - * Orders API constructor. |
|
36 | - * |
|
37 | - * @param PayPalApi $api |
|
38 | - */ |
|
39 | - public function __construct(PayPalApi $api) |
|
40 | - { |
|
41 | - $this->api = $api; |
|
42 | - $this->request_url = $this->api->apiEndpoint() . 'checkout/orders/'; |
|
43 | - } |
|
34 | + /** |
|
35 | + * Orders API constructor. |
|
36 | + * |
|
37 | + * @param PayPalApi $api |
|
38 | + */ |
|
39 | + public function __construct(PayPalApi $api) |
|
40 | + { |
|
41 | + $this->api = $api; |
|
42 | + $this->request_url = $this->api->apiEndpoint() . 'checkout/orders/'; |
|
43 | + } |
|
44 | 44 | } |
@@ -20,92 +20,92 @@ |
||
20 | 20 | */ |
21 | 21 | class CaptureOrder extends OrdersApi |
22 | 22 | { |
23 | - /** |
|
24 | - * Currency. |
|
25 | - * |
|
26 | - * @var string |
|
27 | - */ |
|
28 | - protected string $currency_code; |
|
23 | + /** |
|
24 | + * Currency. |
|
25 | + * |
|
26 | + * @var string |
|
27 | + */ |
|
28 | + protected string $currency_code; |
|
29 | 29 | |
30 | - /** |
|
31 | - * Transaction this order is for. |
|
32 | - * |
|
33 | - * @var EE_Transaction |
|
34 | - */ |
|
35 | - protected EE_Transaction $transaction; |
|
30 | + /** |
|
31 | + * Transaction this order is for. |
|
32 | + * |
|
33 | + * @var EE_Transaction |
|
34 | + */ |
|
35 | + protected EE_Transaction $transaction; |
|
36 | 36 | |
37 | 37 | |
38 | - /** |
|
39 | - * CaptureOrder constructor. |
|
40 | - * |
|
41 | - * @param PayPalApi $api |
|
42 | - * @param EE_Transaction $transaction |
|
43 | - * @param string $order_id |
|
44 | - */ |
|
45 | - public function __construct(PayPalApi $api, EE_Transaction $transaction, string $order_id) |
|
46 | - { |
|
47 | - parent::__construct($api); |
|
48 | - $this->transaction = $transaction; |
|
49 | - $this->order_id = $order_id; |
|
50 | - $this->currency_code = CurrencyManager::currencyCode(); |
|
51 | - $this->request_url = $this->request_url . $order_id . '/capture'; |
|
52 | - } |
|
38 | + /** |
|
39 | + * CaptureOrder constructor. |
|
40 | + * |
|
41 | + * @param PayPalApi $api |
|
42 | + * @param EE_Transaction $transaction |
|
43 | + * @param string $order_id |
|
44 | + */ |
|
45 | + public function __construct(PayPalApi $api, EE_Transaction $transaction, string $order_id) |
|
46 | + { |
|
47 | + parent::__construct($api); |
|
48 | + $this->transaction = $transaction; |
|
49 | + $this->order_id = $order_id; |
|
50 | + $this->currency_code = CurrencyManager::currencyCode(); |
|
51 | + $this->request_url = $this->request_url . $order_id . '/capture'; |
|
52 | + } |
|
53 | 53 | |
54 | 54 | |
55 | - /** |
|
56 | - * Capture payment for PayPal Order. |
|
57 | - * |
|
58 | - * @return array |
|
59 | - */ |
|
60 | - public function capture(): array |
|
61 | - { |
|
62 | - // Create Order request. |
|
63 | - $capture_response = $this->api->sendRequest([], $this->request_url); |
|
64 | - return $this->validateOrder($capture_response); |
|
65 | - } |
|
55 | + /** |
|
56 | + * Capture payment for PayPal Order. |
|
57 | + * |
|
58 | + * @return array |
|
59 | + */ |
|
60 | + public function capture(): array |
|
61 | + { |
|
62 | + // Create Order request. |
|
63 | + $capture_response = $this->api->sendRequest([], $this->request_url); |
|
64 | + return $this->validateOrder($capture_response); |
|
65 | + } |
|
66 | 66 | |
67 | 67 | |
68 | - /** |
|
69 | - * Makes sure that we have received an Order back from the API call. |
|
70 | - * |
|
71 | - * @param $response |
|
72 | - * @return array |
|
73 | - * @throws EE_Error |
|
74 | - * @throws ReflectionException |
|
75 | - */ |
|
76 | - public function validateOrder($response): array |
|
77 | - { |
|
78 | - $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
|
79 | - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
80 | - // We got a direct error response. Not valid. Return that error. |
|
81 | - if (! empty($response['error'])) { |
|
82 | - return $response; |
|
83 | - } |
|
84 | - // This also could be a retry capture, so consider this valid, if order already captured. |
|
85 | - if (! empty($response['message']['details']['issue']) |
|
86 | - && $response['message']['details']['issue'] === 'ORDER_ALREADY_CAPTURED' |
|
87 | - ) { |
|
88 | - // Need to make sure we pass on the order ID. |
|
89 | - if (empty($response['id'])) { |
|
90 | - $response['id'] = $this->order_id; |
|
91 | - } |
|
92 | - $response['status'] = 'ORDER_ALREADY_CAPTURED'; |
|
93 | - return $response; |
|
94 | - } |
|
95 | - // A success capture should return the order ID. |
|
96 | - if (! isset($response['id'])) { |
|
97 | - $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
|
98 | - try { |
|
99 | - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
100 | - } catch (EE_Error | ReflectionException $e) { |
|
101 | - // Just continue. |
|
102 | - } |
|
103 | - return [ |
|
104 | - 'error' => $response['error'] ?? 'missing_order', |
|
105 | - 'message' => $response['message'] ?? $message, |
|
106 | - 'name' => $response['name'] ?? 'UNKNOWN_ERROR', |
|
107 | - ]; |
|
108 | - } |
|
109 | - return $response; |
|
110 | - } |
|
68 | + /** |
|
69 | + * Makes sure that we have received an Order back from the API call. |
|
70 | + * |
|
71 | + * @param $response |
|
72 | + * @return array |
|
73 | + * @throws EE_Error |
|
74 | + * @throws ReflectionException |
|
75 | + */ |
|
76 | + public function validateOrder($response): array |
|
77 | + { |
|
78 | + $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
|
79 | + PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
80 | + // We got a direct error response. Not valid. Return that error. |
|
81 | + if (! empty($response['error'])) { |
|
82 | + return $response; |
|
83 | + } |
|
84 | + // This also could be a retry capture, so consider this valid, if order already captured. |
|
85 | + if (! empty($response['message']['details']['issue']) |
|
86 | + && $response['message']['details']['issue'] === 'ORDER_ALREADY_CAPTURED' |
|
87 | + ) { |
|
88 | + // Need to make sure we pass on the order ID. |
|
89 | + if (empty($response['id'])) { |
|
90 | + $response['id'] = $this->order_id; |
|
91 | + } |
|
92 | + $response['status'] = 'ORDER_ALREADY_CAPTURED'; |
|
93 | + return $response; |
|
94 | + } |
|
95 | + // A success capture should return the order ID. |
|
96 | + if (! isset($response['id'])) { |
|
97 | + $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
|
98 | + try { |
|
99 | + PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
100 | + } catch (EE_Error | ReflectionException $e) { |
|
101 | + // Just continue. |
|
102 | + } |
|
103 | + return [ |
|
104 | + 'error' => $response['error'] ?? 'missing_order', |
|
105 | + 'message' => $response['message'] ?? $message, |
|
106 | + 'name' => $response['name'] ?? 'UNKNOWN_ERROR', |
|
107 | + ]; |
|
108 | + } |
|
109 | + return $response; |
|
110 | + } |
|
111 | 111 | } |
@@ -48,7 +48,7 @@ discard block |
||
48 | 48 | $this->transaction = $transaction; |
49 | 49 | $this->order_id = $order_id; |
50 | 50 | $this->currency_code = CurrencyManager::currencyCode(); |
51 | - $this->request_url = $this->request_url . $order_id . '/capture'; |
|
51 | + $this->request_url = $this->request_url.$order_id.'/capture'; |
|
52 | 52 | } |
53 | 53 | |
54 | 54 | |
@@ -78,11 +78,11 @@ discard block |
||
78 | 78 | $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
79 | 79 | PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
80 | 80 | // We got a direct error response. Not valid. Return that error. |
81 | - if (! empty($response['error'])) { |
|
81 | + if ( ! empty($response['error'])) { |
|
82 | 82 | return $response; |
83 | 83 | } |
84 | 84 | // This also could be a retry capture, so consider this valid, if order already captured. |
85 | - if (! empty($response['message']['details']['issue']) |
|
85 | + if ( ! empty($response['message']['details']['issue']) |
|
86 | 86 | && $response['message']['details']['issue'] === 'ORDER_ALREADY_CAPTURED' |
87 | 87 | ) { |
88 | 88 | // Need to make sure we pass on the order ID. |
@@ -93,7 +93,7 @@ discard block |
||
93 | 93 | return $response; |
94 | 94 | } |
95 | 95 | // A success capture should return the order ID. |
96 | - if (! isset($response['id'])) { |
|
96 | + if ( ! isset($response['id'])) { |
|
97 | 97 | $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
98 | 98 | try { |
99 | 99 | PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
@@ -13,115 +13,115 @@ |
||
13 | 13 | */ |
14 | 14 | class FirstPartyPayPalApi extends PayPalApi |
15 | 15 | { |
16 | - /** |
|
17 | - * Client ID. Used to process payments. |
|
18 | - * |
|
19 | - * @var string |
|
20 | - */ |
|
21 | - protected string $client_id = ''; |
|
22 | - |
|
23 | - /** |
|
24 | - * Client secret. Used to process payments. |
|
25 | - * |
|
26 | - * @var string |
|
27 | - */ |
|
28 | - protected string $client_secret = ''; |
|
29 | - |
|
30 | - /** |
|
31 | - * BN Code. Partner-Attribution-Id. |
|
32 | - * |
|
33 | - * @var string |
|
34 | - */ |
|
35 | - protected string $bn_code = ''; |
|
36 | - |
|
37 | - |
|
38 | - /** |
|
39 | - * @param string $client_id |
|
40 | - * @param string $client_secret |
|
41 | - * @param string $bn_code |
|
42 | - * @param bool $sandbox_mode |
|
43 | - */ |
|
44 | - public function __construct(string $client_id, string $client_secret, string $bn_code, bool $sandbox_mode = true) |
|
45 | - { |
|
46 | - parent::__construct($sandbox_mode); |
|
47 | - $this->client_id = $client_id; |
|
48 | - $this->client_secret = $client_secret; |
|
49 | - $this->bn_code = $bn_code; |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - * Send an API request. |
|
55 | - * |
|
56 | - * @param array $body_parameters |
|
57 | - * @param string $endpoint |
|
58 | - * @param string $method |
|
59 | - * @param array $headers |
|
60 | - * @return Object|array |
|
61 | - */ |
|
62 | - public function sendRequest(array $body_parameters, string $endpoint, string $method = 'POST', array $headers = []) |
|
63 | - { |
|
64 | - $request_parameters = $this->getRequestParameters($body_parameters, $method, $headers); |
|
65 | - return $this->request($endpoint, $request_parameters); |
|
66 | - } |
|
67 | - |
|
68 | - |
|
69 | - /** |
|
70 | - * Build the request parameters. |
|
71 | - * |
|
72 | - * @param array $body_parameters |
|
73 | - * @param string $method |
|
74 | - * @param array $headers |
|
75 | - * @return array |
|
76 | - */ |
|
77 | - private function getRequestParameters(array $body_parameters, string $method, array $headers): array |
|
78 | - { |
|
79 | - $request_parameters = [ |
|
80 | - 'method' => $method, |
|
81 | - 'timeout' => 60, |
|
82 | - 'redirection' => 5, |
|
83 | - 'blocking' => true, |
|
84 | - ]; |
|
85 | - $default_headers = [ |
|
86 | - 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
87 | - 'PayPal-Partner-Attribution-Id' => $this->bn_code, |
|
88 | - 'Content-Type' => 'application/json', |
|
89 | - 'Authorization' => 'Basic ' . base64_encode( |
|
90 | - $this->client_id . ':' . $this->client_secret |
|
91 | - ), |
|
92 | - ]; |
|
93 | - $request_parameters['headers'] = array_merge($default_headers, $headers); |
|
94 | - // Add body if this is a POST request. |
|
95 | - if ($body_parameters && ($method === 'POST' || $method === 'PUT')) { |
|
96 | - $request_parameters['body'] = json_encode($body_parameters); |
|
97 | - } |
|
98 | - return $request_parameters; |
|
99 | - } |
|
100 | - |
|
101 | - |
|
102 | - /** |
|
103 | - * @return string |
|
104 | - */ |
|
105 | - public function clientId(): string |
|
106 | - { |
|
107 | - return $this->client_id; |
|
108 | - } |
|
109 | - |
|
110 | - |
|
111 | - /** |
|
112 | - * @return string |
|
113 | - */ |
|
114 | - public function clientSecret(): string |
|
115 | - { |
|
116 | - return $this->client_secret; |
|
117 | - } |
|
118 | - |
|
119 | - |
|
120 | - /** |
|
121 | - * @return string |
|
122 | - */ |
|
123 | - public function bnCode(): string |
|
124 | - { |
|
125 | - return $this->bn_code; |
|
126 | - } |
|
16 | + /** |
|
17 | + * Client ID. Used to process payments. |
|
18 | + * |
|
19 | + * @var string |
|
20 | + */ |
|
21 | + protected string $client_id = ''; |
|
22 | + |
|
23 | + /** |
|
24 | + * Client secret. Used to process payments. |
|
25 | + * |
|
26 | + * @var string |
|
27 | + */ |
|
28 | + protected string $client_secret = ''; |
|
29 | + |
|
30 | + /** |
|
31 | + * BN Code. Partner-Attribution-Id. |
|
32 | + * |
|
33 | + * @var string |
|
34 | + */ |
|
35 | + protected string $bn_code = ''; |
|
36 | + |
|
37 | + |
|
38 | + /** |
|
39 | + * @param string $client_id |
|
40 | + * @param string $client_secret |
|
41 | + * @param string $bn_code |
|
42 | + * @param bool $sandbox_mode |
|
43 | + */ |
|
44 | + public function __construct(string $client_id, string $client_secret, string $bn_code, bool $sandbox_mode = true) |
|
45 | + { |
|
46 | + parent::__construct($sandbox_mode); |
|
47 | + $this->client_id = $client_id; |
|
48 | + $this->client_secret = $client_secret; |
|
49 | + $this->bn_code = $bn_code; |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + * Send an API request. |
|
55 | + * |
|
56 | + * @param array $body_parameters |
|
57 | + * @param string $endpoint |
|
58 | + * @param string $method |
|
59 | + * @param array $headers |
|
60 | + * @return Object|array |
|
61 | + */ |
|
62 | + public function sendRequest(array $body_parameters, string $endpoint, string $method = 'POST', array $headers = []) |
|
63 | + { |
|
64 | + $request_parameters = $this->getRequestParameters($body_parameters, $method, $headers); |
|
65 | + return $this->request($endpoint, $request_parameters); |
|
66 | + } |
|
67 | + |
|
68 | + |
|
69 | + /** |
|
70 | + * Build the request parameters. |
|
71 | + * |
|
72 | + * @param array $body_parameters |
|
73 | + * @param string $method |
|
74 | + * @param array $headers |
|
75 | + * @return array |
|
76 | + */ |
|
77 | + private function getRequestParameters(array $body_parameters, string $method, array $headers): array |
|
78 | + { |
|
79 | + $request_parameters = [ |
|
80 | + 'method' => $method, |
|
81 | + 'timeout' => 60, |
|
82 | + 'redirection' => 5, |
|
83 | + 'blocking' => true, |
|
84 | + ]; |
|
85 | + $default_headers = [ |
|
86 | + 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
87 | + 'PayPal-Partner-Attribution-Id' => $this->bn_code, |
|
88 | + 'Content-Type' => 'application/json', |
|
89 | + 'Authorization' => 'Basic ' . base64_encode( |
|
90 | + $this->client_id . ':' . $this->client_secret |
|
91 | + ), |
|
92 | + ]; |
|
93 | + $request_parameters['headers'] = array_merge($default_headers, $headers); |
|
94 | + // Add body if this is a POST request. |
|
95 | + if ($body_parameters && ($method === 'POST' || $method === 'PUT')) { |
|
96 | + $request_parameters['body'] = json_encode($body_parameters); |
|
97 | + } |
|
98 | + return $request_parameters; |
|
99 | + } |
|
100 | + |
|
101 | + |
|
102 | + /** |
|
103 | + * @return string |
|
104 | + */ |
|
105 | + public function clientId(): string |
|
106 | + { |
|
107 | + return $this->client_id; |
|
108 | + } |
|
109 | + |
|
110 | + |
|
111 | + /** |
|
112 | + * @return string |
|
113 | + */ |
|
114 | + public function clientSecret(): string |
|
115 | + { |
|
116 | + return $this->client_secret; |
|
117 | + } |
|
118 | + |
|
119 | + |
|
120 | + /** |
|
121 | + * @return string |
|
122 | + */ |
|
123 | + public function bnCode(): string |
|
124 | + { |
|
125 | + return $this->bn_code; |
|
126 | + } |
|
127 | 127 | } |
@@ -15,72 +15,72 @@ |
||
15 | 15 | */ |
16 | 16 | abstract class PayPalApi |
17 | 17 | { |
18 | - /** |
|
19 | - * @var bool Debug mode enabled ? |
|
20 | - */ |
|
21 | - protected bool $sandbox_mode; |
|
18 | + /** |
|
19 | + * @var bool Debug mode enabled ? |
|
20 | + */ |
|
21 | + protected bool $sandbox_mode; |
|
22 | 22 | |
23 | - /** |
|
24 | - * API request/response validation helper. |
|
25 | - * |
|
26 | - * @var ResponseInspector |
|
27 | - */ |
|
28 | - protected ResponseInspector $inspector; |
|
23 | + /** |
|
24 | + * API request/response validation helper. |
|
25 | + * |
|
26 | + * @var ResponseInspector |
|
27 | + */ |
|
28 | + protected ResponseInspector $inspector; |
|
29 | 29 | |
30 | - /** |
|
31 | - * @var string PayPal API endpoint. |
|
32 | - */ |
|
33 | - protected string $api_endpoint = ''; |
|
30 | + /** |
|
31 | + * @var string PayPal API endpoint. |
|
32 | + */ |
|
33 | + protected string $api_endpoint = ''; |
|
34 | 34 | |
35 | 35 | |
36 | - /** |
|
37 | - * @param bool $sandbox_mode |
|
38 | - */ |
|
39 | - public function __construct(bool $sandbox_mode = true) { |
|
40 | - $this->sandbox_mode = $sandbox_mode; |
|
41 | - // Is this a sandbox request. |
|
42 | - $this->api_endpoint = $this->sandbox_mode |
|
43 | - ? 'https://api-m.sandbox.paypal.com/v2/' |
|
44 | - : 'https://api-m.paypal.com/v2/'; |
|
45 | - $this->inspector = new ResponseInspector(); |
|
46 | - } |
|
36 | + /** |
|
37 | + * @param bool $sandbox_mode |
|
38 | + */ |
|
39 | + public function __construct(bool $sandbox_mode = true) { |
|
40 | + $this->sandbox_mode = $sandbox_mode; |
|
41 | + // Is this a sandbox request. |
|
42 | + $this->api_endpoint = $this->sandbox_mode |
|
43 | + ? 'https://api-m.sandbox.paypal.com/v2/' |
|
44 | + : 'https://api-m.paypal.com/v2/'; |
|
45 | + $this->inspector = new ResponseInspector(); |
|
46 | + } |
|
47 | 47 | |
48 | 48 | |
49 | - /** |
|
50 | - * Send an API request. |
|
51 | - * |
|
52 | - * @param string $endpoint |
|
53 | - * @param array $request_parameters |
|
54 | - * @return Object|array |
|
55 | - */ |
|
56 | - public function request(string $endpoint, array $request_parameters) |
|
57 | - { |
|
58 | - // Sent the API request. |
|
59 | - $response = wp_remote_request($endpoint, $request_parameters); |
|
60 | - // Validate the response. |
|
61 | - $this->inspector->validateResponse($response); |
|
62 | - if (! $this->inspector->isValid()) { |
|
63 | - PayPalLogger::errorLog($this->inspector->error()['message'], [$endpoint, $request_parameters, $response]); |
|
64 | - return $this->inspector->error(); |
|
65 | - } |
|
66 | - // Decode the parameters. |
|
67 | - $api_response = json_decode($response['body'], true); |
|
68 | - // Validate parameters. |
|
69 | - $this->inspector->validateParameters($api_response); |
|
70 | - if (! $this->inspector->isValid()) { |
|
71 | - PayPalLogger::errorLog($this->inspector->error()['message'], [$endpoint, $request_parameters, $response]); |
|
72 | - return $this->inspector->error(); |
|
73 | - } |
|
74 | - // All seem ok, return the response. |
|
75 | - return $api_response; |
|
76 | - } |
|
49 | + /** |
|
50 | + * Send an API request. |
|
51 | + * |
|
52 | + * @param string $endpoint |
|
53 | + * @param array $request_parameters |
|
54 | + * @return Object|array |
|
55 | + */ |
|
56 | + public function request(string $endpoint, array $request_parameters) |
|
57 | + { |
|
58 | + // Sent the API request. |
|
59 | + $response = wp_remote_request($endpoint, $request_parameters); |
|
60 | + // Validate the response. |
|
61 | + $this->inspector->validateResponse($response); |
|
62 | + if (! $this->inspector->isValid()) { |
|
63 | + PayPalLogger::errorLog($this->inspector->error()['message'], [$endpoint, $request_parameters, $response]); |
|
64 | + return $this->inspector->error(); |
|
65 | + } |
|
66 | + // Decode the parameters. |
|
67 | + $api_response = json_decode($response['body'], true); |
|
68 | + // Validate parameters. |
|
69 | + $this->inspector->validateParameters($api_response); |
|
70 | + if (! $this->inspector->isValid()) { |
|
71 | + PayPalLogger::errorLog($this->inspector->error()['message'], [$endpoint, $request_parameters, $response]); |
|
72 | + return $this->inspector->error(); |
|
73 | + } |
|
74 | + // All seem ok, return the response. |
|
75 | + return $api_response; |
|
76 | + } |
|
77 | 77 | |
78 | 78 | |
79 | - /** |
|
80 | - * @return string |
|
81 | - */ |
|
82 | - public function apiEndpoint(): string |
|
83 | - { |
|
84 | - return $this->api_endpoint; |
|
85 | - } |
|
79 | + /** |
|
80 | + * @return string |
|
81 | + */ |
|
82 | + public function apiEndpoint(): string |
|
83 | + { |
|
84 | + return $this->api_endpoint; |
|
85 | + } |
|
86 | 86 | } |
@@ -13,127 +13,127 @@ |
||
13 | 13 | */ |
14 | 14 | class ThirdPartyPayPalApi extends PayPalApi |
15 | 15 | { |
16 | - /** |
|
17 | - * Partner access token used to process payments. |
|
18 | - * |
|
19 | - * @var string |
|
20 | - */ |
|
21 | - protected string $access_token = ''; |
|
16 | + /** |
|
17 | + * Partner access token used to process payments. |
|
18 | + * |
|
19 | + * @var string |
|
20 | + */ |
|
21 | + protected string $access_token = ''; |
|
22 | 22 | |
23 | - /** |
|
24 | - * Partner Client ID. |
|
25 | - * |
|
26 | - * @var string |
|
27 | - */ |
|
28 | - protected string $partner_client_id = ''; |
|
23 | + /** |
|
24 | + * Partner Client ID. |
|
25 | + * |
|
26 | + * @var string |
|
27 | + */ |
|
28 | + protected string $partner_client_id = ''; |
|
29 | 29 | |
30 | - /** |
|
31 | - * Merchant (seller) merchant ID. |
|
32 | - * |
|
33 | - * @var string |
|
34 | - */ |
|
35 | - protected string $payer_id = ''; |
|
30 | + /** |
|
31 | + * Merchant (seller) merchant ID. |
|
32 | + * |
|
33 | + * @var string |
|
34 | + */ |
|
35 | + protected string $payer_id = ''; |
|
36 | 36 | |
37 | - /** |
|
38 | - * BN Code. Partner-Attribution-Id. |
|
39 | - * |
|
40 | - * @var string |
|
41 | - */ |
|
42 | - protected string $bn_code = ''; |
|
37 | + /** |
|
38 | + * BN Code. Partner-Attribution-Id. |
|
39 | + * |
|
40 | + * @var string |
|
41 | + */ |
|
42 | + protected string $bn_code = ''; |
|
43 | 43 | |
44 | 44 | |
45 | - /** |
|
46 | - * @param string $access_token |
|
47 | - * @param string $bn_code |
|
48 | - * @param string $partner_client_id |
|
49 | - * @param string $payer_id |
|
50 | - * @param bool $sandbox_mode |
|
51 | - */ |
|
52 | - public function __construct( |
|
53 | - string $access_token, |
|
54 | - string $bn_code, |
|
55 | - string $partner_client_id = '', |
|
56 | - string $payer_id = '', |
|
57 | - bool $sandbox_mode = true |
|
58 | - ) { |
|
59 | - parent::__construct($sandbox_mode); |
|
60 | - $this->access_token = $access_token; |
|
61 | - $this->partner_client_id = $partner_client_id; |
|
62 | - $this->payer_id = $payer_id; |
|
63 | - $this->bn_code = $bn_code; |
|
64 | - } |
|
45 | + /** |
|
46 | + * @param string $access_token |
|
47 | + * @param string $bn_code |
|
48 | + * @param string $partner_client_id |
|
49 | + * @param string $payer_id |
|
50 | + * @param bool $sandbox_mode |
|
51 | + */ |
|
52 | + public function __construct( |
|
53 | + string $access_token, |
|
54 | + string $bn_code, |
|
55 | + string $partner_client_id = '', |
|
56 | + string $payer_id = '', |
|
57 | + bool $sandbox_mode = true |
|
58 | + ) { |
|
59 | + parent::__construct($sandbox_mode); |
|
60 | + $this->access_token = $access_token; |
|
61 | + $this->partner_client_id = $partner_client_id; |
|
62 | + $this->payer_id = $payer_id; |
|
63 | + $this->bn_code = $bn_code; |
|
64 | + } |
|
65 | 65 | |
66 | 66 | |
67 | - /** |
|
68 | - * Send an API request. |
|
69 | - * |
|
70 | - * @param array $body_parameters |
|
71 | - * @param string $endpoint |
|
72 | - * @param string $method |
|
73 | - * @param array $headers |
|
74 | - * @return Object|array |
|
75 | - */ |
|
76 | - public function sendRequest(array $body_parameters, string $endpoint, string $method = 'POST', array $headers = []) |
|
77 | - { |
|
78 | - $request_parameters = $this->getRequestParameters($body_parameters, $method, $headers); |
|
79 | - return $this->request($endpoint, $request_parameters); |
|
80 | - } |
|
67 | + /** |
|
68 | + * Send an API request. |
|
69 | + * |
|
70 | + * @param array $body_parameters |
|
71 | + * @param string $endpoint |
|
72 | + * @param string $method |
|
73 | + * @param array $headers |
|
74 | + * @return Object|array |
|
75 | + */ |
|
76 | + public function sendRequest(array $body_parameters, string $endpoint, string $method = 'POST', array $headers = []) |
|
77 | + { |
|
78 | + $request_parameters = $this->getRequestParameters($body_parameters, $method, $headers); |
|
79 | + return $this->request($endpoint, $request_parameters); |
|
80 | + } |
|
81 | 81 | |
82 | 82 | |
83 | - /** |
|
84 | - * Build the request parameters. |
|
85 | - * |
|
86 | - * @param array $body_parameters |
|
87 | - * @param string $method |
|
88 | - * @param array $headers |
|
89 | - * @return array |
|
90 | - */ |
|
91 | - private function getRequestParameters(array $body_parameters, string $method, array $headers): array |
|
92 | - { |
|
93 | - $request_parameters = [ |
|
94 | - 'method' => $method, |
|
95 | - ]; |
|
96 | - $default_headers = [ |
|
97 | - 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
98 | - 'PayPal-Partner-Attribution-Id' => $this->bnCode(), |
|
99 | - 'Content-Type' => 'application/json', |
|
100 | - 'Authorization' => 'Bearer ' . $this->accessToken(), |
|
101 | - ]; |
|
102 | - // If we have merchant credentials then we are onboard and can do requests on behalf of the seller. |
|
103 | - if ($this->partner_client_id && $this->payer_id) { |
|
104 | - $assertion1 = [ |
|
105 | - 'alg' => 'none', |
|
106 | - ]; |
|
107 | - $assertion2 = [ |
|
108 | - 'iss' => $this->partner_client_id, |
|
109 | - 'payer_id' => $this->payer_id, |
|
110 | - ]; |
|
111 | - $default_headers['PayPal-Auth-Assertion'] = base64_encode(json_encode($assertion1, JSON_HEX_APOS)) . '.' . |
|
112 | - base64_encode(json_encode($assertion2, JSON_HEX_APOS)) . '.'; |
|
113 | - } |
|
114 | - $request_parameters['headers'] = array_merge($default_headers, $headers); |
|
115 | - // Add body if this is a POST request. |
|
116 | - if ($body_parameters && ($method === 'POST' || $method === 'PUT')) { |
|
117 | - $request_parameters['body'] = json_encode($body_parameters); |
|
118 | - } |
|
119 | - return $request_parameters; |
|
120 | - } |
|
83 | + /** |
|
84 | + * Build the request parameters. |
|
85 | + * |
|
86 | + * @param array $body_parameters |
|
87 | + * @param string $method |
|
88 | + * @param array $headers |
|
89 | + * @return array |
|
90 | + */ |
|
91 | + private function getRequestParameters(array $body_parameters, string $method, array $headers): array |
|
92 | + { |
|
93 | + $request_parameters = [ |
|
94 | + 'method' => $method, |
|
95 | + ]; |
|
96 | + $default_headers = [ |
|
97 | + 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
98 | + 'PayPal-Partner-Attribution-Id' => $this->bnCode(), |
|
99 | + 'Content-Type' => 'application/json', |
|
100 | + 'Authorization' => 'Bearer ' . $this->accessToken(), |
|
101 | + ]; |
|
102 | + // If we have merchant credentials then we are onboard and can do requests on behalf of the seller. |
|
103 | + if ($this->partner_client_id && $this->payer_id) { |
|
104 | + $assertion1 = [ |
|
105 | + 'alg' => 'none', |
|
106 | + ]; |
|
107 | + $assertion2 = [ |
|
108 | + 'iss' => $this->partner_client_id, |
|
109 | + 'payer_id' => $this->payer_id, |
|
110 | + ]; |
|
111 | + $default_headers['PayPal-Auth-Assertion'] = base64_encode(json_encode($assertion1, JSON_HEX_APOS)) . '.' . |
|
112 | + base64_encode(json_encode($assertion2, JSON_HEX_APOS)) . '.'; |
|
113 | + } |
|
114 | + $request_parameters['headers'] = array_merge($default_headers, $headers); |
|
115 | + // Add body if this is a POST request. |
|
116 | + if ($body_parameters && ($method === 'POST' || $method === 'PUT')) { |
|
117 | + $request_parameters['body'] = json_encode($body_parameters); |
|
118 | + } |
|
119 | + return $request_parameters; |
|
120 | + } |
|
121 | 121 | |
122 | 122 | |
123 | - /** |
|
124 | - * @return string |
|
125 | - */ |
|
126 | - public function accessToken(): string |
|
127 | - { |
|
128 | - return $this->access_token; |
|
129 | - } |
|
123 | + /** |
|
124 | + * @return string |
|
125 | + */ |
|
126 | + public function accessToken(): string |
|
127 | + { |
|
128 | + return $this->access_token; |
|
129 | + } |
|
130 | 130 | |
131 | 131 | |
132 | - /** |
|
133 | - * @return string |
|
134 | - */ |
|
135 | - public function bnCode(): string |
|
136 | - { |
|
137 | - return $this->bn_code; |
|
138 | - } |
|
132 | + /** |
|
133 | + * @return string |
|
134 | + */ |
|
135 | + public function bnCode(): string |
|
136 | + { |
|
137 | + return $this->bn_code; |
|
138 | + } |
|
139 | 139 | } |
@@ -21,459 +21,459 @@ |
||
21 | 21 | */ |
22 | 22 | class EED_PayPalCommerce extends EED_Module |
23 | 23 | { |
24 | - /** |
|
25 | - * @return EED_Module |
|
26 | - * @throws EE_Error |
|
27 | - * @throws ReflectionException |
|
28 | - */ |
|
29 | - public static function instance(): EED_Module |
|
30 | - { |
|
31 | - return parent::get_instance(__CLASS__); |
|
32 | - } |
|
33 | - |
|
34 | - |
|
35 | - /** |
|
36 | - * Run - initial module setup. |
|
37 | - * |
|
38 | - * @param WP $WP |
|
39 | - * @return void |
|
40 | - */ |
|
41 | - public function run($WP) |
|
42 | - { |
|
43 | - } |
|
44 | - |
|
45 | - |
|
46 | - /** |
|
47 | - * For hooking into EE Core and other modules. |
|
48 | - * |
|
49 | - * @return void |
|
50 | - */ |
|
51 | - public static function set_hooks(): void |
|
52 | - { |
|
53 | - if (DbStatus::isOnline()) { |
|
54 | - // Don't load PM on the front-end if not Connected. |
|
55 | - add_filter( |
|
56 | - 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
57 | - [__CLASS__, 'filterPaymentMethods'], |
|
58 | - 100, |
|
59 | - 3 |
|
60 | - ); |
|
61 | - } |
|
62 | - } |
|
63 | - |
|
64 | - |
|
65 | - /** |
|
66 | - * For hooking into EE Core and other modules Admin. |
|
67 | - * |
|
68 | - * @return void |
|
69 | - */ |
|
70 | - public static function set_hooks_admin(): void |
|
71 | - { |
|
72 | - if (DbStatus::isOnline()) { |
|
73 | - // Create an Order. |
|
74 | - add_action('wp_ajax_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
75 | - add_action('wp_ajax_nopriv_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
76 | - // Capture the Order. |
|
77 | - add_action('wp_ajax_eeaPPCCaptureOrder', [__CLASS__, 'captureOrderRequest']); |
|
78 | - add_action('wp_ajax_nopriv_eeaPPCCaptureOrder', [__CLASS__, 'captureOrderRequest']); |
|
79 | - // Log errors from the JS side. |
|
80 | - add_action('wp_ajax_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
81 | - add_action('wp_ajax_nopriv_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
82 | - // Don't load PM in the admin if not Connected. |
|
83 | - add_filter( |
|
84 | - 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
85 | - [__CLASS__, 'filterPaymentMethods'], |
|
86 | - 100, |
|
87 | - 3 |
|
88 | - ); |
|
89 | - } |
|
90 | - } |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * Create the order and return its data as JSON. |
|
95 | - * (AJAX) |
|
96 | - * |
|
97 | - * @return void |
|
98 | - * @throws EE_Error |
|
99 | - * @throws ReflectionException |
|
100 | - */ |
|
101 | - public static function createOrderRequest(): void |
|
102 | - { |
|
103 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
104 | - $request = EED_Module::getRequest(); |
|
105 | - $post_params = $request->postParams(); |
|
106 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
107 | - PayPalLogger::errorLogAndExit( |
|
108 | - esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
|
109 | - $post_params |
|
110 | - ); |
|
111 | - } |
|
112 | - $transaction = EED_PayPalCommerce::getTransaction(); |
|
113 | - $billing_info = $post_params['billing_info'] ?? []; |
|
114 | - if ($billing_info) { |
|
115 | - $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
|
116 | - $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
|
117 | - } |
|
118 | - if (! $transaction) { |
|
119 | - PayPalLogger::errorLogAndExit( |
|
120 | - esc_html__('Transaction info not found.', 'event_espresso'), |
|
121 | - $post_params, |
|
122 | - $paypal_pm |
|
123 | - ); |
|
124 | - } |
|
125 | - $order_data = EED_PayPalCommerce::createOrder($transaction, $billing_info, $paypal_pm); |
|
126 | - wp_send_json($order_data); |
|
127 | - } |
|
128 | - |
|
129 | - |
|
130 | - /** |
|
131 | - * Capture the order and return status in JSON. |
|
132 | - * (AJAX) |
|
133 | - * |
|
134 | - * @return void |
|
135 | - */ |
|
136 | - public static function captureOrderRequest(): void |
|
137 | - { |
|
138 | - $error_message = false; |
|
139 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
140 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
141 | - $error_message = esc_html__('Payment method not found (capture Order).', 'event_espresso'); |
|
142 | - } |
|
143 | - $transaction = EED_PayPalCommerce::getTransaction(); |
|
144 | - if (! $transaction) { |
|
145 | - $error_message = esc_html__('Transaction not found.', 'event_espresso'); |
|
146 | - } |
|
147 | - $order_id = EED_Module::getRequest()->getRequestParam('order_id', '', DataType::STRING); |
|
148 | - if (! $order_id) { |
|
149 | - $error_message = esc_html__('Order ID missing.', 'event_espresso'); |
|
150 | - } |
|
151 | - // We had an error. Log and EXIT. |
|
152 | - if ($error_message) { |
|
153 | - PayPalLogger::errorLogAndExit($error_message, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
154 | - } |
|
155 | - $capture_response = EED_PayPalCommerce::captureOrder($transaction, $paypal_pm, $order_id); |
|
156 | - wp_send_json($capture_response); |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * Create a new Order using the PP API. |
|
162 | - * |
|
163 | - * @param EE_Transaction $transaction |
|
164 | - * @param array $billing_info |
|
165 | - * @param EE_Payment_Method $paypal_pm |
|
166 | - * @return array |
|
167 | - * @throws EE_Error |
|
168 | - * @throws ReflectionException |
|
169 | - */ |
|
170 | - public static function createOrder( |
|
171 | - EE_Transaction $transaction, |
|
172 | - array $billing_info, |
|
173 | - EE_Payment_Method $paypal_pm |
|
174 | - ): array { |
|
175 | - $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
|
176 | - if (! $create_order_api instanceof CreateOrder) { |
|
177 | - return [ |
|
178 | - 'error' => 'CREATE_ORDER_API_FAULT', |
|
179 | - 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
|
180 | - ]; |
|
181 | - } |
|
182 | - $order = $create_order_api->create(); |
|
183 | - if (isset($order['error'])) { |
|
184 | - return [ |
|
185 | - 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR', |
|
186 | - 'message' => $order['message'], |
|
187 | - ]; |
|
188 | - } |
|
189 | - return [ |
|
190 | - 'pp_order_id' => $order['id'], |
|
191 | - ]; |
|
192 | - } |
|
193 | - |
|
194 | - |
|
195 | - /** |
|
196 | - * Create a new Order using the PP API. |
|
197 | - * |
|
198 | - * @param EE_Transaction $transaction |
|
199 | - * @param EE_Payment_Method $paypal_pm |
|
200 | - * @param string $order_id |
|
201 | - * @return array |
|
202 | - */ |
|
203 | - public static function captureOrder( |
|
204 | - EE_Transaction $transaction, |
|
205 | - EE_Payment_Method $paypal_pm, |
|
206 | - string $order_id |
|
207 | - ): array { |
|
208 | - $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
|
209 | - if (! $capture_order_api instanceof CaptureOrder) { |
|
210 | - return [ |
|
211 | - 'error' => 'CAPTURE_ORDER_API_FAULT', |
|
212 | - 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
|
213 | - ]; |
|
214 | - } |
|
215 | - $order = $capture_order_api->capture(); |
|
216 | - if (isset($order['error'])) { |
|
217 | - return $order; |
|
218 | - } |
|
219 | - // Attach the transaction ID to this order. |
|
220 | - try { |
|
221 | - $order['ee_txn_id'] = $transaction->ID(); |
|
222 | - } catch (Exception $e) { |
|
223 | - // Just don't set the txn id. |
|
224 | - } |
|
225 | - // If this was a capture request on an already Captured order, try using the initial capture data (if any saved) |
|
226 | - // that has more information on the order than this retry capture response. |
|
227 | - if ($order['status'] === 'ORDER_ALREADY_CAPTURED' |
|
228 | - || empty($order['purchase_units'][0]['payments']['captures'][0]['amount']['value']) |
|
229 | - ) { |
|
230 | - // Get the previous order. Maybe it's the same order but will hold a bit more information. |
|
231 | - $previous_order = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_LAST_ORDER); |
|
232 | - if ($previous_order['id'] === $order['id'] |
|
233 | - && ! empty($previous_order['purchase_units'][0]['payments']['captures'][0]['amount']['value']) |
|
234 | - ) { |
|
235 | - // Can use the initially captured order information. |
|
236 | - $order = $previous_order; |
|
237 | - } |
|
238 | - } |
|
239 | - // Save this order details. |
|
240 | - PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_LAST_ORDER, $order); |
|
241 | - $nonce = wp_create_nonce(Domain::CAPTURE_ORDER_NONCE_NAME); |
|
242 | - return [ |
|
243 | - 'pp_order_nonce' => $nonce, |
|
244 | - 'pp_order_id' => $order['id'], |
|
245 | - 'pp_order_status' => $order['status'] ?? 'ORDER_STATUS_UNKNOWN', |
|
246 | - 'pp_order_amount' => $order['purchase_units'][0]['payments']['captures'][0]['amount']['value'] ?? '', |
|
247 | - ]; |
|
248 | - } |
|
249 | - |
|
250 | - |
|
251 | - /** |
|
252 | - * Create an Order for this transaction. |
|
253 | - * |
|
254 | - * @param EE_Transaction $transaction |
|
255 | - * @param array $billing_info |
|
256 | - * @param EE_Payment_Method $paypal_pm |
|
257 | - * @return CreateOrder|null |
|
258 | - */ |
|
259 | - public static function getCreateOrderApi( |
|
260 | - EE_Transaction $transaction, |
|
261 | - array $billing_info, |
|
262 | - EE_Payment_Method $paypal_pm |
|
263 | - ): ?CreateOrder { |
|
264 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
265 | - if (! $paypal_api instanceof PayPalApi) { |
|
266 | - return null; |
|
267 | - } |
|
268 | - return new CreateOrder($paypal_api, $transaction, $billing_info); |
|
269 | - } |
|
270 | - |
|
271 | - |
|
272 | - /** |
|
273 | - * Create an Order for this transaction. |
|
274 | - * |
|
275 | - * @param EE_Transaction $transaction |
|
276 | - * @param EE_Payment_Method $paypal_pm |
|
277 | - * @param string $order_id |
|
278 | - * @return CaptureOrder|null |
|
279 | - */ |
|
280 | - public static function getCaptureOrderApi( |
|
281 | - EE_Transaction $transaction, |
|
282 | - EE_Payment_Method $paypal_pm, |
|
283 | - string $order_id |
|
284 | - ): ?CaptureOrder { |
|
285 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
286 | - if (! $paypal_api instanceof PayPalApi) { |
|
287 | - return null; |
|
288 | - } |
|
289 | - return new CaptureOrder($paypal_api, $transaction, $order_id); |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * Return a PayPal API object, or false on failure. |
|
295 | - * |
|
296 | - * @param EE_Payment_Method $paypal_pm |
|
297 | - * @return PayPalApi|null |
|
298 | - * @throws EE_Error |
|
299 | - * @throws ReflectionException |
|
300 | - */ |
|
301 | - public static function getPayPalApi(EE_Payment_Method $paypal_pm): ?PayPalApi |
|
302 | - { |
|
303 | - // Try getting the first party credentials to determine if this is a first party integration that's active. |
|
304 | - $client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_ID); |
|
305 | - $client_secret = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_SECRET); |
|
306 | - $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
307 | - if ($client_id && $client_secret) { |
|
308 | - return new FirstPartyPayPalApi($client_id, $client_secret, $bn_code, $paypal_pm->debug_mode()); |
|
309 | - } |
|
310 | - // Third party integration credentials: |
|
311 | - $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
312 | - if (! $access_token || ! $bn_code) { |
|
313 | - return null; |
|
314 | - } |
|
315 | - $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
|
316 | - $payer_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?: ''; |
|
317 | - return new ThirdPartyPayPalApi( |
|
318 | - $access_token, $bn_code, $partner_client_id, $payer_id, $paypal_pm->debug_mode() |
|
319 | - ); |
|
320 | - } |
|
321 | - |
|
322 | - |
|
323 | - /** |
|
324 | - * Requests a client token. |
|
325 | - * |
|
326 | - * @param EE_Payment_Method $paypal_pm |
|
327 | - * @return array |
|
328 | - */ |
|
329 | - public static function requestClientToken(EE_Payment_Method $paypal_pm): array |
|
330 | - { |
|
331 | - $error = [ |
|
332 | - 'error' => 'GET_CLIENT_TOKEN_FAULT', |
|
333 | - ]; |
|
334 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
335 | - if (! $paypal_api instanceof PayPalApi) { |
|
336 | - $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
|
337 | - return $error; |
|
338 | - } |
|
339 | - $client_token_api = new ClientToken($paypal_api, $paypal_pm->debug_mode()); |
|
340 | - $client_token = $client_token_api->getToken(); |
|
341 | - if (isset($client_token['error'])) { |
|
342 | - return $client_token; |
|
343 | - } |
|
344 | - if (empty($client_token)) { |
|
345 | - $error['message'] = esc_html__('Client token not valid.', 'event_espresso'); |
|
346 | - return $error; |
|
347 | - } |
|
348 | - return $client_token; |
|
349 | - } |
|
350 | - |
|
351 | - |
|
352 | - /** |
|
353 | - * Retrieve the payment method from the provided data. |
|
354 | - * |
|
355 | - * @return EE_Transaction|null |
|
356 | - */ |
|
357 | - public static function getTransaction(): ?EE_Transaction |
|
358 | - { |
|
359 | - try { |
|
360 | - $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
|
361 | - $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
362 | - if (! $transaction instanceof EE_Transaction) { |
|
363 | - PayPalLogger::errorLog( |
|
364 | - esc_html__('No transaction found by ID:', 'event_espresso'), |
|
365 | - EED_Module::getRequest()->postParams() |
|
366 | - ); |
|
367 | - return null; |
|
368 | - } |
|
369 | - } catch (Exception $e) { |
|
370 | - return null; |
|
371 | - } |
|
372 | - return $transaction; |
|
373 | - } |
|
374 | - |
|
375 | - |
|
376 | - /** |
|
377 | - * Return a PayPal API object, or false on failure. |
|
378 | - * |
|
379 | - * @param EE_Payment_Method $paypal_pm |
|
380 | - * @return bool |
|
381 | - */ |
|
382 | - public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
|
383 | - { |
|
384 | - $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
|
385 | - return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
386 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
387 | - } |
|
388 | - |
|
389 | - |
|
390 | - /** |
|
391 | - * Retrieve the payment method from the provided data. |
|
392 | - * |
|
393 | - * @return EE_Payment_Method|null |
|
394 | - */ |
|
395 | - public static function getPaymentMethod(): ?EE_Payment_Method |
|
396 | - { |
|
397 | - try { |
|
398 | - // Check if all required parameters are present. |
|
399 | - $pm_slug = EED_Module::getRequest()->getRequestParam('payment_method'); |
|
400 | - $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_slug); |
|
401 | - if ($payment_method instanceof EE_Payment_Method) { |
|
402 | - return $payment_method; |
|
403 | - } |
|
404 | - } catch (Exception $e) { |
|
405 | - return null; |
|
406 | - } |
|
407 | - return null; |
|
408 | - } |
|
409 | - |
|
410 | - |
|
411 | - /** |
|
412 | - * Log JS error. |
|
413 | - * |
|
414 | - * @return void |
|
415 | - */ |
|
416 | - public static function logJsError(): void |
|
417 | - { |
|
418 | - // Default to the "first" PayPal checkout PM. |
|
419 | - $request = EED_Module::getRequest(); |
|
420 | - $pm_slug = $request->getRequestParam('pm_slug', Domain::PM_SLUG); |
|
421 | - $payment_method = null; |
|
422 | - $txn_id = 'unknown'; |
|
423 | - try { |
|
424 | - $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pm_slug); |
|
425 | - $txn_id = sanitize_text_field($request->getRequestParam('txn_id', '-')); |
|
426 | - } catch (Exception $e) { |
|
427 | - // Don't throw out anything, log at least something. |
|
428 | - } |
|
429 | - PayPalLogger::errorLog("JS Error on transaction: {$txn_id}", $request->postParams(), $payment_method); |
|
430 | - } |
|
431 | - |
|
432 | - |
|
433 | - /** |
|
434 | - * Filter the Payment Methods list. |
|
435 | - * |
|
436 | - * @param EE_Payment_Method[] $payment_methods |
|
437 | - * @param EE_Transaction $transaction |
|
438 | - * @param string $scope @see EEM_Payment_Method::get_all_for_events |
|
439 | - * @return array |
|
440 | - * @throws EE_Error |
|
441 | - * @throws ReflectionException |
|
442 | - */ |
|
443 | - public static function filterPaymentMethods( |
|
444 | - array $payment_methods, |
|
445 | - EE_Transaction $transaction, |
|
446 | - string $scope |
|
447 | - ): array { |
|
448 | - // Don't allow this PM on the checkout page if not Connected. |
|
449 | - foreach ($payment_methods as $key => $pm) { |
|
450 | - // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
|
451 | - if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
|
452 | - unset($payment_methods[ $key ]); |
|
453 | - } |
|
454 | - } |
|
455 | - return $payment_methods; |
|
456 | - } |
|
457 | - |
|
458 | - |
|
459 | - /** |
|
460 | - * Get all active states. |
|
461 | - * |
|
462 | - * @return array |
|
463 | - * @throws EE_Error |
|
464 | - * @throws ReflectionException |
|
465 | - */ |
|
466 | - public static function getActiveStates(): array |
|
467 | - { |
|
468 | - $state_options = []; |
|
469 | - $states = EEM_State::instance()->get_all_active_states(); |
|
470 | - if (! empty($states)) { |
|
471 | - foreach ($states as $numeral => $state) { |
|
472 | - if ($state instanceof EE_State) { |
|
473 | - $state_options[ $numeral ] = $state->abbrev(); |
|
474 | - } |
|
475 | - } |
|
476 | - } |
|
477 | - return $state_options; |
|
478 | - } |
|
24 | + /** |
|
25 | + * @return EED_Module |
|
26 | + * @throws EE_Error |
|
27 | + * @throws ReflectionException |
|
28 | + */ |
|
29 | + public static function instance(): EED_Module |
|
30 | + { |
|
31 | + return parent::get_instance(__CLASS__); |
|
32 | + } |
|
33 | + |
|
34 | + |
|
35 | + /** |
|
36 | + * Run - initial module setup. |
|
37 | + * |
|
38 | + * @param WP $WP |
|
39 | + * @return void |
|
40 | + */ |
|
41 | + public function run($WP) |
|
42 | + { |
|
43 | + } |
|
44 | + |
|
45 | + |
|
46 | + /** |
|
47 | + * For hooking into EE Core and other modules. |
|
48 | + * |
|
49 | + * @return void |
|
50 | + */ |
|
51 | + public static function set_hooks(): void |
|
52 | + { |
|
53 | + if (DbStatus::isOnline()) { |
|
54 | + // Don't load PM on the front-end if not Connected. |
|
55 | + add_filter( |
|
56 | + 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
57 | + [__CLASS__, 'filterPaymentMethods'], |
|
58 | + 100, |
|
59 | + 3 |
|
60 | + ); |
|
61 | + } |
|
62 | + } |
|
63 | + |
|
64 | + |
|
65 | + /** |
|
66 | + * For hooking into EE Core and other modules Admin. |
|
67 | + * |
|
68 | + * @return void |
|
69 | + */ |
|
70 | + public static function set_hooks_admin(): void |
|
71 | + { |
|
72 | + if (DbStatus::isOnline()) { |
|
73 | + // Create an Order. |
|
74 | + add_action('wp_ajax_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
75 | + add_action('wp_ajax_nopriv_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
76 | + // Capture the Order. |
|
77 | + add_action('wp_ajax_eeaPPCCaptureOrder', [__CLASS__, 'captureOrderRequest']); |
|
78 | + add_action('wp_ajax_nopriv_eeaPPCCaptureOrder', [__CLASS__, 'captureOrderRequest']); |
|
79 | + // Log errors from the JS side. |
|
80 | + add_action('wp_ajax_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
81 | + add_action('wp_ajax_nopriv_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
82 | + // Don't load PM in the admin if not Connected. |
|
83 | + add_filter( |
|
84 | + 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
85 | + [__CLASS__, 'filterPaymentMethods'], |
|
86 | + 100, |
|
87 | + 3 |
|
88 | + ); |
|
89 | + } |
|
90 | + } |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * Create the order and return its data as JSON. |
|
95 | + * (AJAX) |
|
96 | + * |
|
97 | + * @return void |
|
98 | + * @throws EE_Error |
|
99 | + * @throws ReflectionException |
|
100 | + */ |
|
101 | + public static function createOrderRequest(): void |
|
102 | + { |
|
103 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
104 | + $request = EED_Module::getRequest(); |
|
105 | + $post_params = $request->postParams(); |
|
106 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
107 | + PayPalLogger::errorLogAndExit( |
|
108 | + esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
|
109 | + $post_params |
|
110 | + ); |
|
111 | + } |
|
112 | + $transaction = EED_PayPalCommerce::getTransaction(); |
|
113 | + $billing_info = $post_params['billing_info'] ?? []; |
|
114 | + if ($billing_info) { |
|
115 | + $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
|
116 | + $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
|
117 | + } |
|
118 | + if (! $transaction) { |
|
119 | + PayPalLogger::errorLogAndExit( |
|
120 | + esc_html__('Transaction info not found.', 'event_espresso'), |
|
121 | + $post_params, |
|
122 | + $paypal_pm |
|
123 | + ); |
|
124 | + } |
|
125 | + $order_data = EED_PayPalCommerce::createOrder($transaction, $billing_info, $paypal_pm); |
|
126 | + wp_send_json($order_data); |
|
127 | + } |
|
128 | + |
|
129 | + |
|
130 | + /** |
|
131 | + * Capture the order and return status in JSON. |
|
132 | + * (AJAX) |
|
133 | + * |
|
134 | + * @return void |
|
135 | + */ |
|
136 | + public static function captureOrderRequest(): void |
|
137 | + { |
|
138 | + $error_message = false; |
|
139 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
140 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
141 | + $error_message = esc_html__('Payment method not found (capture Order).', 'event_espresso'); |
|
142 | + } |
|
143 | + $transaction = EED_PayPalCommerce::getTransaction(); |
|
144 | + if (! $transaction) { |
|
145 | + $error_message = esc_html__('Transaction not found.', 'event_espresso'); |
|
146 | + } |
|
147 | + $order_id = EED_Module::getRequest()->getRequestParam('order_id', '', DataType::STRING); |
|
148 | + if (! $order_id) { |
|
149 | + $error_message = esc_html__('Order ID missing.', 'event_espresso'); |
|
150 | + } |
|
151 | + // We had an error. Log and EXIT. |
|
152 | + if ($error_message) { |
|
153 | + PayPalLogger::errorLogAndExit($error_message, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
154 | + } |
|
155 | + $capture_response = EED_PayPalCommerce::captureOrder($transaction, $paypal_pm, $order_id); |
|
156 | + wp_send_json($capture_response); |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * Create a new Order using the PP API. |
|
162 | + * |
|
163 | + * @param EE_Transaction $transaction |
|
164 | + * @param array $billing_info |
|
165 | + * @param EE_Payment_Method $paypal_pm |
|
166 | + * @return array |
|
167 | + * @throws EE_Error |
|
168 | + * @throws ReflectionException |
|
169 | + */ |
|
170 | + public static function createOrder( |
|
171 | + EE_Transaction $transaction, |
|
172 | + array $billing_info, |
|
173 | + EE_Payment_Method $paypal_pm |
|
174 | + ): array { |
|
175 | + $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
|
176 | + if (! $create_order_api instanceof CreateOrder) { |
|
177 | + return [ |
|
178 | + 'error' => 'CREATE_ORDER_API_FAULT', |
|
179 | + 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
|
180 | + ]; |
|
181 | + } |
|
182 | + $order = $create_order_api->create(); |
|
183 | + if (isset($order['error'])) { |
|
184 | + return [ |
|
185 | + 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR', |
|
186 | + 'message' => $order['message'], |
|
187 | + ]; |
|
188 | + } |
|
189 | + return [ |
|
190 | + 'pp_order_id' => $order['id'], |
|
191 | + ]; |
|
192 | + } |
|
193 | + |
|
194 | + |
|
195 | + /** |
|
196 | + * Create a new Order using the PP API. |
|
197 | + * |
|
198 | + * @param EE_Transaction $transaction |
|
199 | + * @param EE_Payment_Method $paypal_pm |
|
200 | + * @param string $order_id |
|
201 | + * @return array |
|
202 | + */ |
|
203 | + public static function captureOrder( |
|
204 | + EE_Transaction $transaction, |
|
205 | + EE_Payment_Method $paypal_pm, |
|
206 | + string $order_id |
|
207 | + ): array { |
|
208 | + $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
|
209 | + if (! $capture_order_api instanceof CaptureOrder) { |
|
210 | + return [ |
|
211 | + 'error' => 'CAPTURE_ORDER_API_FAULT', |
|
212 | + 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
|
213 | + ]; |
|
214 | + } |
|
215 | + $order = $capture_order_api->capture(); |
|
216 | + if (isset($order['error'])) { |
|
217 | + return $order; |
|
218 | + } |
|
219 | + // Attach the transaction ID to this order. |
|
220 | + try { |
|
221 | + $order['ee_txn_id'] = $transaction->ID(); |
|
222 | + } catch (Exception $e) { |
|
223 | + // Just don't set the txn id. |
|
224 | + } |
|
225 | + // If this was a capture request on an already Captured order, try using the initial capture data (if any saved) |
|
226 | + // that has more information on the order than this retry capture response. |
|
227 | + if ($order['status'] === 'ORDER_ALREADY_CAPTURED' |
|
228 | + || empty($order['purchase_units'][0]['payments']['captures'][0]['amount']['value']) |
|
229 | + ) { |
|
230 | + // Get the previous order. Maybe it's the same order but will hold a bit more information. |
|
231 | + $previous_order = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_LAST_ORDER); |
|
232 | + if ($previous_order['id'] === $order['id'] |
|
233 | + && ! empty($previous_order['purchase_units'][0]['payments']['captures'][0]['amount']['value']) |
|
234 | + ) { |
|
235 | + // Can use the initially captured order information. |
|
236 | + $order = $previous_order; |
|
237 | + } |
|
238 | + } |
|
239 | + // Save this order details. |
|
240 | + PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_LAST_ORDER, $order); |
|
241 | + $nonce = wp_create_nonce(Domain::CAPTURE_ORDER_NONCE_NAME); |
|
242 | + return [ |
|
243 | + 'pp_order_nonce' => $nonce, |
|
244 | + 'pp_order_id' => $order['id'], |
|
245 | + 'pp_order_status' => $order['status'] ?? 'ORDER_STATUS_UNKNOWN', |
|
246 | + 'pp_order_amount' => $order['purchase_units'][0]['payments']['captures'][0]['amount']['value'] ?? '', |
|
247 | + ]; |
|
248 | + } |
|
249 | + |
|
250 | + |
|
251 | + /** |
|
252 | + * Create an Order for this transaction. |
|
253 | + * |
|
254 | + * @param EE_Transaction $transaction |
|
255 | + * @param array $billing_info |
|
256 | + * @param EE_Payment_Method $paypal_pm |
|
257 | + * @return CreateOrder|null |
|
258 | + */ |
|
259 | + public static function getCreateOrderApi( |
|
260 | + EE_Transaction $transaction, |
|
261 | + array $billing_info, |
|
262 | + EE_Payment_Method $paypal_pm |
|
263 | + ): ?CreateOrder { |
|
264 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
265 | + if (! $paypal_api instanceof PayPalApi) { |
|
266 | + return null; |
|
267 | + } |
|
268 | + return new CreateOrder($paypal_api, $transaction, $billing_info); |
|
269 | + } |
|
270 | + |
|
271 | + |
|
272 | + /** |
|
273 | + * Create an Order for this transaction. |
|
274 | + * |
|
275 | + * @param EE_Transaction $transaction |
|
276 | + * @param EE_Payment_Method $paypal_pm |
|
277 | + * @param string $order_id |
|
278 | + * @return CaptureOrder|null |
|
279 | + */ |
|
280 | + public static function getCaptureOrderApi( |
|
281 | + EE_Transaction $transaction, |
|
282 | + EE_Payment_Method $paypal_pm, |
|
283 | + string $order_id |
|
284 | + ): ?CaptureOrder { |
|
285 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
286 | + if (! $paypal_api instanceof PayPalApi) { |
|
287 | + return null; |
|
288 | + } |
|
289 | + return new CaptureOrder($paypal_api, $transaction, $order_id); |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * Return a PayPal API object, or false on failure. |
|
295 | + * |
|
296 | + * @param EE_Payment_Method $paypal_pm |
|
297 | + * @return PayPalApi|null |
|
298 | + * @throws EE_Error |
|
299 | + * @throws ReflectionException |
|
300 | + */ |
|
301 | + public static function getPayPalApi(EE_Payment_Method $paypal_pm): ?PayPalApi |
|
302 | + { |
|
303 | + // Try getting the first party credentials to determine if this is a first party integration that's active. |
|
304 | + $client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_ID); |
|
305 | + $client_secret = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_SECRET); |
|
306 | + $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
307 | + if ($client_id && $client_secret) { |
|
308 | + return new FirstPartyPayPalApi($client_id, $client_secret, $bn_code, $paypal_pm->debug_mode()); |
|
309 | + } |
|
310 | + // Third party integration credentials: |
|
311 | + $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
312 | + if (! $access_token || ! $bn_code) { |
|
313 | + return null; |
|
314 | + } |
|
315 | + $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
|
316 | + $payer_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?: ''; |
|
317 | + return new ThirdPartyPayPalApi( |
|
318 | + $access_token, $bn_code, $partner_client_id, $payer_id, $paypal_pm->debug_mode() |
|
319 | + ); |
|
320 | + } |
|
321 | + |
|
322 | + |
|
323 | + /** |
|
324 | + * Requests a client token. |
|
325 | + * |
|
326 | + * @param EE_Payment_Method $paypal_pm |
|
327 | + * @return array |
|
328 | + */ |
|
329 | + public static function requestClientToken(EE_Payment_Method $paypal_pm): array |
|
330 | + { |
|
331 | + $error = [ |
|
332 | + 'error' => 'GET_CLIENT_TOKEN_FAULT', |
|
333 | + ]; |
|
334 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
335 | + if (! $paypal_api instanceof PayPalApi) { |
|
336 | + $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
|
337 | + return $error; |
|
338 | + } |
|
339 | + $client_token_api = new ClientToken($paypal_api, $paypal_pm->debug_mode()); |
|
340 | + $client_token = $client_token_api->getToken(); |
|
341 | + if (isset($client_token['error'])) { |
|
342 | + return $client_token; |
|
343 | + } |
|
344 | + if (empty($client_token)) { |
|
345 | + $error['message'] = esc_html__('Client token not valid.', 'event_espresso'); |
|
346 | + return $error; |
|
347 | + } |
|
348 | + return $client_token; |
|
349 | + } |
|
350 | + |
|
351 | + |
|
352 | + /** |
|
353 | + * Retrieve the payment method from the provided data. |
|
354 | + * |
|
355 | + * @return EE_Transaction|null |
|
356 | + */ |
|
357 | + public static function getTransaction(): ?EE_Transaction |
|
358 | + { |
|
359 | + try { |
|
360 | + $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
|
361 | + $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
362 | + if (! $transaction instanceof EE_Transaction) { |
|
363 | + PayPalLogger::errorLog( |
|
364 | + esc_html__('No transaction found by ID:', 'event_espresso'), |
|
365 | + EED_Module::getRequest()->postParams() |
|
366 | + ); |
|
367 | + return null; |
|
368 | + } |
|
369 | + } catch (Exception $e) { |
|
370 | + return null; |
|
371 | + } |
|
372 | + return $transaction; |
|
373 | + } |
|
374 | + |
|
375 | + |
|
376 | + /** |
|
377 | + * Return a PayPal API object, or false on failure. |
|
378 | + * |
|
379 | + * @param EE_Payment_Method $paypal_pm |
|
380 | + * @return bool |
|
381 | + */ |
|
382 | + public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
|
383 | + { |
|
384 | + $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
|
385 | + return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
386 | + && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
387 | + } |
|
388 | + |
|
389 | + |
|
390 | + /** |
|
391 | + * Retrieve the payment method from the provided data. |
|
392 | + * |
|
393 | + * @return EE_Payment_Method|null |
|
394 | + */ |
|
395 | + public static function getPaymentMethod(): ?EE_Payment_Method |
|
396 | + { |
|
397 | + try { |
|
398 | + // Check if all required parameters are present. |
|
399 | + $pm_slug = EED_Module::getRequest()->getRequestParam('payment_method'); |
|
400 | + $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_slug); |
|
401 | + if ($payment_method instanceof EE_Payment_Method) { |
|
402 | + return $payment_method; |
|
403 | + } |
|
404 | + } catch (Exception $e) { |
|
405 | + return null; |
|
406 | + } |
|
407 | + return null; |
|
408 | + } |
|
409 | + |
|
410 | + |
|
411 | + /** |
|
412 | + * Log JS error. |
|
413 | + * |
|
414 | + * @return void |
|
415 | + */ |
|
416 | + public static function logJsError(): void |
|
417 | + { |
|
418 | + // Default to the "first" PayPal checkout PM. |
|
419 | + $request = EED_Module::getRequest(); |
|
420 | + $pm_slug = $request->getRequestParam('pm_slug', Domain::PM_SLUG); |
|
421 | + $payment_method = null; |
|
422 | + $txn_id = 'unknown'; |
|
423 | + try { |
|
424 | + $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pm_slug); |
|
425 | + $txn_id = sanitize_text_field($request->getRequestParam('txn_id', '-')); |
|
426 | + } catch (Exception $e) { |
|
427 | + // Don't throw out anything, log at least something. |
|
428 | + } |
|
429 | + PayPalLogger::errorLog("JS Error on transaction: {$txn_id}", $request->postParams(), $payment_method); |
|
430 | + } |
|
431 | + |
|
432 | + |
|
433 | + /** |
|
434 | + * Filter the Payment Methods list. |
|
435 | + * |
|
436 | + * @param EE_Payment_Method[] $payment_methods |
|
437 | + * @param EE_Transaction $transaction |
|
438 | + * @param string $scope @see EEM_Payment_Method::get_all_for_events |
|
439 | + * @return array |
|
440 | + * @throws EE_Error |
|
441 | + * @throws ReflectionException |
|
442 | + */ |
|
443 | + public static function filterPaymentMethods( |
|
444 | + array $payment_methods, |
|
445 | + EE_Transaction $transaction, |
|
446 | + string $scope |
|
447 | + ): array { |
|
448 | + // Don't allow this PM on the checkout page if not Connected. |
|
449 | + foreach ($payment_methods as $key => $pm) { |
|
450 | + // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
|
451 | + if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
|
452 | + unset($payment_methods[ $key ]); |
|
453 | + } |
|
454 | + } |
|
455 | + return $payment_methods; |
|
456 | + } |
|
457 | + |
|
458 | + |
|
459 | + /** |
|
460 | + * Get all active states. |
|
461 | + * |
|
462 | + * @return array |
|
463 | + * @throws EE_Error |
|
464 | + * @throws ReflectionException |
|
465 | + */ |
|
466 | + public static function getActiveStates(): array |
|
467 | + { |
|
468 | + $state_options = []; |
|
469 | + $states = EEM_State::instance()->get_all_active_states(); |
|
470 | + if (! empty($states)) { |
|
471 | + foreach ($states as $numeral => $state) { |
|
472 | + if ($state instanceof EE_State) { |
|
473 | + $state_options[ $numeral ] = $state->abbrev(); |
|
474 | + } |
|
475 | + } |
|
476 | + } |
|
477 | + return $state_options; |
|
478 | + } |
|
479 | 479 | } |
@@ -103,7 +103,7 @@ discard block |
||
103 | 103 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
104 | 104 | $request = EED_Module::getRequest(); |
105 | 105 | $post_params = $request->postParams(); |
106 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
106 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
107 | 107 | PayPalLogger::errorLogAndExit( |
108 | 108 | esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
109 | 109 | $post_params |
@@ -115,7 +115,7 @@ discard block |
||
115 | 115 | $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
116 | 116 | $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
117 | 117 | } |
118 | - if (! $transaction) { |
|
118 | + if ( ! $transaction) { |
|
119 | 119 | PayPalLogger::errorLogAndExit( |
120 | 120 | esc_html__('Transaction info not found.', 'event_espresso'), |
121 | 121 | $post_params, |
@@ -137,15 +137,15 @@ discard block |
||
137 | 137 | { |
138 | 138 | $error_message = false; |
139 | 139 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
140 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
140 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
141 | 141 | $error_message = esc_html__('Payment method not found (capture Order).', 'event_espresso'); |
142 | 142 | } |
143 | 143 | $transaction = EED_PayPalCommerce::getTransaction(); |
144 | - if (! $transaction) { |
|
144 | + if ( ! $transaction) { |
|
145 | 145 | $error_message = esc_html__('Transaction not found.', 'event_espresso'); |
146 | 146 | } |
147 | 147 | $order_id = EED_Module::getRequest()->getRequestParam('order_id', '', DataType::STRING); |
148 | - if (! $order_id) { |
|
148 | + if ( ! $order_id) { |
|
149 | 149 | $error_message = esc_html__('Order ID missing.', 'event_espresso'); |
150 | 150 | } |
151 | 151 | // We had an error. Log and EXIT. |
@@ -173,7 +173,7 @@ discard block |
||
173 | 173 | EE_Payment_Method $paypal_pm |
174 | 174 | ): array { |
175 | 175 | $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
176 | - if (! $create_order_api instanceof CreateOrder) { |
|
176 | + if ( ! $create_order_api instanceof CreateOrder) { |
|
177 | 177 | return [ |
178 | 178 | 'error' => 'CREATE_ORDER_API_FAULT', |
179 | 179 | 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
@@ -206,7 +206,7 @@ discard block |
||
206 | 206 | string $order_id |
207 | 207 | ): array { |
208 | 208 | $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
209 | - if (! $capture_order_api instanceof CaptureOrder) { |
|
209 | + if ( ! $capture_order_api instanceof CaptureOrder) { |
|
210 | 210 | return [ |
211 | 211 | 'error' => 'CAPTURE_ORDER_API_FAULT', |
212 | 212 | 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
@@ -262,7 +262,7 @@ discard block |
||
262 | 262 | EE_Payment_Method $paypal_pm |
263 | 263 | ): ?CreateOrder { |
264 | 264 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
265 | - if (! $paypal_api instanceof PayPalApi) { |
|
265 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
266 | 266 | return null; |
267 | 267 | } |
268 | 268 | return new CreateOrder($paypal_api, $transaction, $billing_info); |
@@ -283,7 +283,7 @@ discard block |
||
283 | 283 | string $order_id |
284 | 284 | ): ?CaptureOrder { |
285 | 285 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
286 | - if (! $paypal_api instanceof PayPalApi) { |
|
286 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
287 | 287 | return null; |
288 | 288 | } |
289 | 289 | return new CaptureOrder($paypal_api, $transaction, $order_id); |
@@ -309,7 +309,7 @@ discard block |
||
309 | 309 | } |
310 | 310 | // Third party integration credentials: |
311 | 311 | $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
312 | - if (! $access_token || ! $bn_code) { |
|
312 | + if ( ! $access_token || ! $bn_code) { |
|
313 | 313 | return null; |
314 | 314 | } |
315 | 315 | $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
@@ -332,7 +332,7 @@ discard block |
||
332 | 332 | 'error' => 'GET_CLIENT_TOKEN_FAULT', |
333 | 333 | ]; |
334 | 334 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
335 | - if (! $paypal_api instanceof PayPalApi) { |
|
335 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
336 | 336 | $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
337 | 337 | return $error; |
338 | 338 | } |
@@ -359,7 +359,7 @@ discard block |
||
359 | 359 | try { |
360 | 360 | $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
361 | 361 | $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
362 | - if (! $transaction instanceof EE_Transaction) { |
|
362 | + if ( ! $transaction instanceof EE_Transaction) { |
|
363 | 363 | PayPalLogger::errorLog( |
364 | 364 | esc_html__('No transaction found by ID:', 'event_espresso'), |
365 | 365 | EED_Module::getRequest()->postParams() |
@@ -382,8 +382,8 @@ discard block |
||
382 | 382 | public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
383 | 383 | { |
384 | 384 | $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
385 | - return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
386 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
385 | + return ! empty($pp_meta_data[Domain::META_KEY_SELLER_MERCHANT_ID]) |
|
386 | + && ! empty($pp_meta_data[Domain::META_KEY_ACCESS_TOKEN]); |
|
387 | 387 | } |
388 | 388 | |
389 | 389 | |
@@ -449,7 +449,7 @@ discard block |
||
449 | 449 | foreach ($payment_methods as $key => $pm) { |
450 | 450 | // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
451 | 451 | if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
452 | - unset($payment_methods[ $key ]); |
|
452 | + unset($payment_methods[$key]); |
|
453 | 453 | } |
454 | 454 | } |
455 | 455 | return $payment_methods; |
@@ -467,10 +467,10 @@ discard block |
||
467 | 467 | { |
468 | 468 | $state_options = []; |
469 | 469 | $states = EEM_State::instance()->get_all_active_states(); |
470 | - if (! empty($states)) { |
|
470 | + if ( ! empty($states)) { |
|
471 | 471 | foreach ($states as $numeral => $state) { |
472 | 472 | if ($state instanceof EE_State) { |
473 | - $state_options[ $numeral ] = $state->abbrev(); |
|
473 | + $state_options[$numeral] = $state->abbrev(); |
|
474 | 474 | } |
475 | 475 | } |
476 | 476 | } |
@@ -20,660 +20,660 @@ |
||
20 | 20 | */ |
21 | 21 | class EED_PayPalOnboard extends EED_Module |
22 | 22 | { |
23 | - /** |
|
24 | - * @return EED_Module |
|
25 | - * @throws EE_Error |
|
26 | - * @throws ReflectionException |
|
27 | - */ |
|
28 | - public static function instance(): EED_Module |
|
29 | - { |
|
30 | - return parent::get_instance(__CLASS__); |
|
31 | - } |
|
32 | - |
|
33 | - |
|
34 | - /** |
|
35 | - * Run - initial module setup. |
|
36 | - * |
|
37 | - * @param WP $WP |
|
38 | - * @return void |
|
39 | - */ |
|
40 | - public function run($WP) |
|
41 | - { |
|
42 | - } |
|
43 | - |
|
44 | - |
|
45 | - /** |
|
46 | - * For hooking into EE Admin Core and other modules. |
|
47 | - * |
|
48 | - * @return void |
|
49 | - */ |
|
50 | - public static function set_hooks_admin(): void |
|
51 | - { |
|
52 | - if (DbStatus::isOnline()) { |
|
53 | - // Get onboarding URL. |
|
54 | - add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']); |
|
55 | - // Catch the return/redirect from PayPal onboarding page. |
|
56 | - add_action('init', [__CLASS__, 'updateOnboardingStatus'], 10); |
|
57 | - // Return the connection/onboard status. |
|
58 | - add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']); |
|
59 | - // Revoke access. |
|
60 | - add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']); |
|
61 | - // Admin notice. |
|
62 | - add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
63 | - } |
|
64 | - } |
|
65 | - |
|
66 | - |
|
67 | - /** |
|
68 | - * Get the onboarding URL. |
|
69 | - * (AJAX) |
|
70 | - * |
|
71 | - * @return void |
|
72 | - */ |
|
73 | - public static function getOnboardingUrl(): void |
|
74 | - { |
|
75 | - $signup_link = ''; |
|
76 | - try { |
|
77 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
78 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
79 | - PayPalLogger::errorLogAndExit( |
|
80 | - esc_html__('No payment method.', 'event_espresso'), |
|
81 | - EED_Module::getRequest()->postParams(), |
|
82 | - $paypal_pm |
|
83 | - ); |
|
84 | - } |
|
85 | - PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams()); |
|
86 | - // $signup_link = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL); |
|
87 | - // $token_expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm); |
|
88 | - // if (! $signup_link || $token_expired) { |
|
89 | - $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm); |
|
90 | - // } |
|
91 | - if (! $signup_link) { |
|
92 | - $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso'); |
|
93 | - PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm); |
|
94 | - } |
|
95 | - PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL, $signup_link); |
|
96 | - } catch (Exception $exception) { |
|
97 | - PayPalLogger::errorLogAndExit($exception->getMessage()); |
|
98 | - } |
|
99 | - // Is it empty (can happen if we didn't get the URL through the API). |
|
100 | - $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#'; |
|
101 | - wp_send_json( |
|
102 | - [ |
|
103 | - 'signup_link' => $signup_link, |
|
104 | - ] |
|
105 | - ); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * Request the sign-up link from PayPal. |
|
111 | - * |
|
112 | - * @param EE_Payment_Method $paypal_pm |
|
113 | - * @param bool $one_time_request |
|
114 | - * @return string |
|
115 | - * @throws EE_Error |
|
116 | - * @throws Exception |
|
117 | - */ |
|
118 | - public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string |
|
119 | - { |
|
120 | - $signup_link = ''; |
|
121 | - // Get the access token. |
|
122 | - $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
123 | - if (! $access_token) { |
|
124 | - $err_msg = esc_html__('Error! No access token.', 'event_espresso'); |
|
125 | - PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm); |
|
126 | - return ''; |
|
127 | - } |
|
128 | - // Request the access token. |
|
129 | - $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm); |
|
130 | - $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
131 | - $post_params = [ |
|
132 | - 'method' => 'POST', |
|
133 | - 'headers' => [ |
|
134 | - 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
135 | - 'Content-Type' => 'application/json', |
|
136 | - 'Authorization' => 'Bearer ' . $access_token, |
|
137 | - 'PayPal-Partner-Attribution-Id' => $bn_code, |
|
138 | - ], |
|
139 | - 'body' => $body_params, |
|
140 | - ]; |
|
141 | - $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals'; |
|
142 | - $response = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params); |
|
143 | - // Check the data we received. |
|
144 | - if (isset($response['error']) || empty($response['links'])) { |
|
145 | - // Did the original access token get replaced by any chance ? |
|
146 | - if (! $one_time_request |
|
147 | - && ! empty($response['message']) |
|
148 | - && $response['message'] === 'Access Token not found in cache' |
|
149 | - ) { |
|
150 | - // Clear all PM metadata and try getting the access token One more time. |
|
151 | - PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
152 | - return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true); |
|
153 | - } |
|
154 | - $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso'); |
|
155 | - PayPalLogger::errorLog($err_msg, $response, $paypal_pm); |
|
156 | - return ''; |
|
157 | - } |
|
158 | - // Now retrieve that sign-up link. |
|
159 | - foreach ($response['links'] as $link) { |
|
160 | - if ($link['rel'] === 'action_url') { |
|
161 | - $signup_link = $link['href'] ?? ''; |
|
162 | - } |
|
163 | - } |
|
164 | - return $signup_link; |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - /** |
|
169 | - * Get the return URL. |
|
170 | - * |
|
171 | - * @param EE_Payment_Method $paypal_pm |
|
172 | - * @return string |
|
173 | - * @throws Exception |
|
174 | - */ |
|
175 | - public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string |
|
176 | - { |
|
177 | - $identifier_string = new OneTimeString($paypal_pm->debug_mode()); |
|
178 | - $tracking_id = $identifier_string->value(); |
|
179 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
180 | - $checkout_type = $request->getRequestParam('checkout_type', 'EXPRESS_CHECKOUT', DataType::STRING); |
|
181 | - // Save the identifier for future use. |
|
182 | - PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id); |
|
183 | - // Assemble the return URL. |
|
184 | - $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm); |
|
185 | - return json_encode([ |
|
186 | - 'tracking_id' => $tracking_id, |
|
187 | - 'operations' => [ |
|
188 | - [ |
|
189 | - 'operation' => 'API_INTEGRATION', |
|
190 | - 'api_integration_preference' => [ |
|
191 | - 'rest_api_integration' => [ |
|
192 | - 'integration_method' => 'PAYPAL', |
|
193 | - 'integration_type' => 'THIRD_PARTY', |
|
194 | - 'third_party_details' => [ |
|
195 | - 'features' => ['PAYMENT', 'REFUND'], |
|
196 | - ], |
|
197 | - ], |
|
198 | - ], |
|
199 | - ], |
|
200 | - ], |
|
201 | - 'products' => [$checkout_type], |
|
202 | - 'legal_consents' => [ |
|
203 | - [ |
|
204 | - 'type' => 'SHARE_DATA_CONSENT', |
|
205 | - 'granted' => true, |
|
206 | - ], |
|
207 | - ], |
|
208 | - 'partner_config_override' => [ |
|
209 | - 'return_url' => $return_url, |
|
210 | - ], |
|
211 | - ]); |
|
212 | - } |
|
213 | - |
|
214 | - |
|
215 | - /** |
|
216 | - * Get the return URL. |
|
217 | - * |
|
218 | - * @param EE_Payment_Method $paypal_pm |
|
219 | - * @return string |
|
220 | - * @throws EE_Error |
|
221 | - * @throws ReflectionException |
|
222 | - */ |
|
223 | - public static function getReturnUrl(EE_Payment_Method $paypal_pm): string |
|
224 | - { |
|
225 | - $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce'); |
|
226 | - $nonce = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN); |
|
227 | - return add_query_arg( |
|
228 | - [ |
|
229 | - 'page' => 'espresso_payment_settings', |
|
230 | - 'webhook_action' => 'eepPpcMerchantOnboard', |
|
231 | - 'payment_method' => $paypal_pm->slug(), |
|
232 | - '_wpnonce' => $wp_nonce, |
|
233 | - 'nonce' => $nonce, |
|
234 | - Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
235 | - ], |
|
236 | - admin_url('admin.php') |
|
237 | - ); |
|
238 | - } |
|
239 | - |
|
240 | - |
|
241 | - /** |
|
242 | - * Redirect to the payment method (PP) settings home page. |
|
243 | - * |
|
244 | - * @return void |
|
245 | - */ |
|
246 | - public static function redirectToPmSettingsHome(): void |
|
247 | - { |
|
248 | - $get_params = EED_Module::getRequest()->getParams(); |
|
249 | - if (empty($get_params['payment_method'])) { |
|
250 | - // Simply do not redirect. |
|
251 | - return; |
|
252 | - } |
|
253 | - $args_to_add = [ |
|
254 | - 'page' => 'espresso_payment_settings', |
|
255 | - 'payment_method' => $get_params['payment_method'], |
|
256 | - ]; |
|
257 | - if (isset($get_params['sandbox_mode'])) { |
|
258 | - $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode']; |
|
259 | - } |
|
260 | - $home_url = add_query_arg($args_to_add, admin_url('admin.php')); |
|
261 | - wp_redirect($home_url); |
|
262 | - exit; |
|
263 | - } |
|
264 | - |
|
265 | - |
|
266 | - /** |
|
267 | - * Check user’s onboarding status. |
|
268 | - * This will handle the user return from the auth page and also check the status via the API. |
|
269 | - * |
|
270 | - * @return void |
|
271 | - * @throws EE_Error |
|
272 | - * @throws ReflectionException |
|
273 | - */ |
|
274 | - public static function updateOnboardingStatus(): void |
|
275 | - { |
|
276 | - // Check if this is the webhook from PayPal. |
|
277 | - if (! isset($_GET['webhook_action'], $_GET['nonce']) |
|
278 | - || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard' |
|
279 | - ) { |
|
280 | - return; // Ignore. |
|
281 | - } |
|
282 | - $get_params = EED_Module::getRequest()->getParams(); |
|
283 | - // Get the payment method. |
|
284 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
285 | - // Check the response (GET) parameters. |
|
286 | - if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
287 | - // Missing parameters. Can't proceed. |
|
288 | - PayPalLogger::errorLog( |
|
289 | - esc_html__('Missing required onboarding parameters.', 'event_espresso'), |
|
290 | - $get_params, |
|
291 | - $paypal_pm |
|
292 | - ); |
|
293 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
294 | - return; |
|
295 | - } |
|
296 | - // Check on the onboarding status (recommended by PP). |
|
297 | - $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding( |
|
298 | - $paypal_pm, |
|
299 | - $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ] |
|
300 | - ); |
|
301 | - if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
302 | - PayPalLogger::errorLog( |
|
303 | - $onboarding_status['message'], |
|
304 | - array_merge($get_params, $onboarding_status), |
|
305 | - $paypal_pm |
|
306 | - ); |
|
307 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
308 | - return; |
|
309 | - } |
|
310 | - // Start saving the setup and info. |
|
311 | - PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status); |
|
312 | - // Save the credentials. |
|
313 | - PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params); |
|
314 | - // If onboarded successfully, remove the onboarding URL. |
|
315 | - PayPalExtraMetaManager::deletePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL); |
|
316 | - // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window. |
|
317 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
318 | - } |
|
319 | - |
|
320 | - |
|
321 | - /** |
|
322 | - * Check if all required parameters for the onboarding status check are present. |
|
323 | - * |
|
324 | - * @param array $data |
|
325 | - * @param mixed $paypal_pm |
|
326 | - * @return bool |
|
327 | - */ |
|
328 | - public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool |
|
329 | - { |
|
330 | - // Check that we have all the required parameters and the nonce is ok. |
|
331 | - if ($paypal_pm instanceof EE_Payment_Method |
|
332 | - && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN) |
|
333 | - && ! empty($data[ Domain::API_PARAM_PARTNER_ID ]) |
|
334 | - && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
335 | - && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ]) |
|
336 | - ) { |
|
337 | - return true; |
|
338 | - } |
|
339 | - return false; |
|
340 | - } |
|
341 | - |
|
342 | - |
|
343 | - /** |
|
344 | - * Get partner access token. |
|
345 | - * |
|
346 | - * @param EE_Payment_Method $paypal_pm |
|
347 | - * @return string |
|
348 | - * @throws EE_Error |
|
349 | - * @throws ReflectionException |
|
350 | - */ |
|
351 | - public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
352 | - { |
|
353 | - // Do we have it saved ? |
|
354 | - $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN); |
|
355 | - $expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm); |
|
356 | - // If we don't have it, request/update it. |
|
357 | - if (! $access_token || $expired) { |
|
358 | - return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
359 | - } |
|
360 | - // Access token is saved as encrypted, so return decrypted. |
|
361 | - return $access_token; |
|
362 | - } |
|
363 | - |
|
364 | - |
|
365 | - /** |
|
366 | - * Get partner access token. |
|
367 | - * |
|
368 | - * @param EE_Payment_Method $paypal_pm |
|
369 | - * @return bool |
|
370 | - */ |
|
371 | - public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool |
|
372 | - { |
|
373 | - $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_EXPIRES_IN); |
|
374 | - if (! $expires_at) { |
|
375 | - return true; |
|
376 | - } |
|
377 | - // Validate the token expiration date. |
|
378 | - $now = time(); |
|
379 | - $minutes_left = round(($expires_at - $now) / 60); |
|
380 | - // Count as expired if less than 60 minutes till expiration left. |
|
381 | - if ($minutes_left <= 60) { |
|
382 | - return true; |
|
383 | - } |
|
384 | - return false; |
|
385 | - } |
|
386 | - |
|
387 | - |
|
388 | - /** |
|
389 | - * Request the partner access token from PayPal and save/update it. |
|
390 | - * |
|
391 | - * @param EE_Payment_Method $paypal_pm |
|
392 | - * @return string |
|
393 | - * @throws EE_Error |
|
394 | - * @throws ReflectionException |
|
395 | - */ |
|
396 | - public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
397 | - { |
|
398 | - $nonce = wp_create_nonce('eea_pp_commerce_get_access_token'); |
|
399 | - // Request the access token. |
|
400 | - $post_args = [ |
|
401 | - 'method' => 'POST', |
|
402 | - 'body' => [ |
|
403 | - 'nonce' => $nonce, |
|
404 | - 'api_version' => 'v1', |
|
405 | - Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
406 | - ], |
|
407 | - ]; |
|
408 | - if (defined('LOCAL_MIDDLEMAN_SERVER')) { |
|
409 | - $post_args['sslverify'] = false; |
|
410 | - } |
|
411 | - $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token'; |
|
412 | - $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args); |
|
413 | - if (isset($response['error'])) { |
|
414 | - return ''; |
|
415 | - } |
|
416 | - // Check the data we received. |
|
417 | - if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
418 | - return ''; |
|
419 | - } |
|
420 | - // If we are here all seems to be ok. Save the token and it's data. |
|
421 | - $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response); |
|
422 | - if (! $saved) { |
|
423 | - return ''; |
|
424 | - } |
|
425 | - return $response['access_token']; |
|
426 | - } |
|
427 | - |
|
428 | - |
|
429 | - /** |
|
430 | - * Request seller onboarding status from PayPal. |
|
431 | - * |
|
432 | - * @param EE_Payment_Method $paypal_pm |
|
433 | - * @param string $merchant_id |
|
434 | - * @return array |
|
435 | - */ |
|
436 | - public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array |
|
437 | - { |
|
438 | - $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id); |
|
439 | - if (! $track_onboarding instanceof TrackSellerOnboarding) { |
|
440 | - $err_msg = esc_html__('Failed to track seller onboarding.', 'event_espresso'); |
|
441 | - return ['error' => 'TRACK_ONBOARDING_FAILED', 'message' => $err_msg]; |
|
442 | - } |
|
443 | - return $track_onboarding->isValid(); |
|
444 | - } |
|
445 | - |
|
446 | - |
|
447 | - /** |
|
448 | - * Returns the Track Seller Onboarding API. |
|
449 | - * |
|
450 | - * @param EE_Payment_Method $paypal_pm |
|
451 | - * @param string $merchant_id |
|
452 | - * @return TrackSellerOnboarding|null |
|
453 | - * @throws EE_Error |
|
454 | - * @throws ReflectionException |
|
455 | - */ |
|
456 | - public static function getTrackOnboardingApi( |
|
457 | - EE_Payment_Method $paypal_pm, |
|
458 | - string $merchant_id |
|
459 | - ): ?TrackSellerOnboarding { |
|
460 | - $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID); |
|
461 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
462 | - if (! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
463 | - return null; |
|
464 | - } |
|
465 | - return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode()); |
|
466 | - } |
|
467 | - |
|
468 | - |
|
469 | - /** |
|
470 | - * Check the onboard status and return the result. |
|
471 | - * (AJAX) |
|
472 | - * |
|
473 | - * @return void |
|
474 | - */ |
|
475 | - public static function getOnboardStatus(): void |
|
476 | - { |
|
477 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
478 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
479 | - $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso'); |
|
480 | - PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
481 | - wp_send_json(['on_board' => false]); |
|
482 | - } |
|
483 | - try { |
|
484 | - $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--'; |
|
485 | - } catch (Exception $e) { |
|
486 | - $seller_id = '--'; |
|
487 | - } |
|
488 | - wp_send_json( |
|
489 | - [ |
|
490 | - 'on_board' => EED_PayPalOnboard::isOnboard($paypal_pm), |
|
491 | - 'seller_id' => $seller_id, |
|
492 | - ] |
|
493 | - ); |
|
494 | - } |
|
495 | - |
|
496 | - |
|
497 | - /** |
|
498 | - * De-authorize the seller. Remove all API credentials. |
|
499 | - * (AJAX) |
|
500 | - * |
|
501 | - * @return void |
|
502 | - */ |
|
503 | - public static function offboard(): void |
|
504 | - { |
|
505 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
506 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
507 | - wp_send_json([ |
|
508 | - 'error' => 'INVALID_PM', |
|
509 | - 'message' => esc_html__( |
|
510 | - 'Invalid payment method. Please refresh the page and try again.', |
|
511 | - 'event_espresso' |
|
512 | - ), |
|
513 | - ]); |
|
514 | - } |
|
515 | - PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
516 | - wp_send_json(['success' => true]); |
|
517 | - } |
|
518 | - |
|
519 | - |
|
520 | - /** |
|
521 | - * Checks if already onboard. |
|
522 | - * |
|
523 | - * @param EE_Payment_Method $payment_method |
|
524 | - * @return boolean |
|
525 | - */ |
|
526 | - public static function isOnboard(EE_Payment_Method $payment_method): bool |
|
527 | - { |
|
528 | - $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method); |
|
529 | - return |
|
530 | - // onborded with a third party integration ? |
|
531 | - (! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
532 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]) |
|
533 | - ) |
|
534 | - // or with the first party integration ? |
|
535 | - || (! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ]) |
|
536 | - && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ]) |
|
537 | - && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ]) |
|
538 | - ); |
|
539 | - } |
|
540 | - |
|
541 | - |
|
542 | - /** |
|
543 | - * Send a request and return a decoded response body. |
|
544 | - * |
|
545 | - * @param EE_Payment_Method $paypal_pm |
|
546 | - * @param string $request_url |
|
547 | - * @param array $request_args |
|
548 | - * @return array |
|
549 | - */ |
|
550 | - public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array |
|
551 | - { |
|
552 | - $error_return = ['error' => true]; |
|
553 | - $response = wp_remote_request($request_url, $request_args); |
|
554 | - if (is_wp_error($response)) { |
|
555 | - $message = $response->get_error_message(); |
|
556 | - PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
557 | - $error_return['message'] = $message; |
|
558 | - return $error_return; |
|
559 | - } |
|
560 | - $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : []; |
|
561 | - if (empty($response_body) || isset($response_body['error'])) { |
|
562 | - $message = $response_body['error_description'] |
|
563 | - ?? sprintf( |
|
564 | - esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'), |
|
565 | - $request_url |
|
566 | - ); |
|
567 | - PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
568 | - $error_return['message'] = $message; |
|
569 | - return $error_return; |
|
570 | - } |
|
571 | - return $response_body; |
|
572 | - } |
|
573 | - |
|
574 | - |
|
575 | - /** |
|
576 | - * Check the response for a partner token request. |
|
577 | - * |
|
578 | - * @param $response |
|
579 | - * @param EE_Payment_Method $paypal_pm |
|
580 | - * @return bool |
|
581 | - */ |
|
582 | - public static function partnerTokenResponseValid($response, EE_Payment_Method $paypal_pm): bool |
|
583 | - { |
|
584 | - // Check the data we received. |
|
585 | - if ( |
|
586 | - empty($response['nonce']) |
|
587 | - || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token') |
|
588 | - || empty($response['access_token']) |
|
589 | - || empty($response['app_id']) |
|
590 | - || empty($response['expires_in']) |
|
591 | - || empty($response['partner_client_id']) |
|
592 | - || empty($response['partner_merchant_id']) |
|
593 | - ) { |
|
594 | - // This is an error. |
|
595 | - $err_msg = esc_html__('Incoming parameter validation failed.', 'event_espresso'); |
|
596 | - PayPalLogger::errorLog($err_msg, (array) $response, $paypal_pm); |
|
597 | - return false; |
|
598 | - } |
|
599 | - return true; |
|
600 | - } |
|
601 | - |
|
602 | - |
|
603 | - /** |
|
604 | - * Returns the base URL to the middleman server. |
|
605 | - * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test |
|
606 | - * |
|
607 | - * @param EE_Payment_Method $payment_method |
|
608 | - * @return string |
|
609 | - * @throws EE_Error |
|
610 | - * @throws ReflectionException |
|
611 | - */ |
|
612 | - public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string |
|
613 | - { |
|
614 | - $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com'; |
|
615 | - // If this PM is used under different provider accounts, you might need an account indicator. |
|
616 | - $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : ''; |
|
617 | - $postfix = $payment_method->debug_mode() ? '_sandbox' : ''; |
|
618 | - $path = 'paypal_commerce' . $account . $postfix; |
|
619 | - return 'https://connect.eventespresso.' . $target . '/' . $path . '/'; |
|
620 | - } |
|
621 | - |
|
622 | - |
|
623 | - /** |
|
624 | - * This Payment Method admin notices. |
|
625 | - * |
|
626 | - * @return void |
|
627 | - * @throws EE_Error |
|
628 | - * @throws ReflectionException |
|
629 | - */ |
|
630 | - public static function adminNotice() |
|
631 | - { |
|
632 | - // Show the notice if PayPal Commerce PM is active but merchant is not onboard. |
|
633 | - $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
634 | - if ($pp_commerce instanceof EE_Payment_Method |
|
635 | - && $pp_commerce->active() |
|
636 | - && ! EED_PayPalOnboard::isOnboard($pp_commerce) |
|
637 | - ) { |
|
638 | - add_action('admin_notices', [__CLASS__, 'notOnboardNotice']); |
|
639 | - } |
|
640 | - } |
|
641 | - |
|
642 | - |
|
643 | - /** |
|
644 | - * Contents of the not onboard admin notice. |
|
645 | - * |
|
646 | - * @return void |
|
647 | - * @throws EE_Error |
|
648 | - * @throws ReflectionException |
|
649 | - */ |
|
650 | - public static function notOnboardNotice() |
|
651 | - { |
|
652 | - $open_anchor = $close_anchor = ''; |
|
653 | - $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
654 | - if ($pp_commerce instanceof EE_Payment_Method) { |
|
655 | - $pm_page = add_query_arg( |
|
656 | - [ |
|
657 | - 'page' => 'espresso_payment_settings', |
|
658 | - 'webhook_action' => 'eepPpcMerchantOnboard', |
|
659 | - 'payment_method' => $pp_commerce->slug(), |
|
660 | - ], |
|
661 | - admin_url('admin.php') |
|
662 | - ); |
|
663 | - $open_anchor = "<a href='$pm_page'>"; |
|
664 | - $close_anchor = "</a>"; |
|
665 | - } |
|
666 | - echo '<div class="error"><p>' |
|
667 | - . sprintf( |
|
668 | - esc_html__( |
|
669 | - '%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.', |
|
670 | - 'event_espresso' |
|
671 | - ), |
|
672 | - '<strong>', |
|
673 | - '</strong>', |
|
674 | - $open_anchor, |
|
675 | - $close_anchor |
|
676 | - ) |
|
677 | - . '</p></div>'; |
|
678 | - } |
|
23 | + /** |
|
24 | + * @return EED_Module |
|
25 | + * @throws EE_Error |
|
26 | + * @throws ReflectionException |
|
27 | + */ |
|
28 | + public static function instance(): EED_Module |
|
29 | + { |
|
30 | + return parent::get_instance(__CLASS__); |
|
31 | + } |
|
32 | + |
|
33 | + |
|
34 | + /** |
|
35 | + * Run - initial module setup. |
|
36 | + * |
|
37 | + * @param WP $WP |
|
38 | + * @return void |
|
39 | + */ |
|
40 | + public function run($WP) |
|
41 | + { |
|
42 | + } |
|
43 | + |
|
44 | + |
|
45 | + /** |
|
46 | + * For hooking into EE Admin Core and other modules. |
|
47 | + * |
|
48 | + * @return void |
|
49 | + */ |
|
50 | + public static function set_hooks_admin(): void |
|
51 | + { |
|
52 | + if (DbStatus::isOnline()) { |
|
53 | + // Get onboarding URL. |
|
54 | + add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']); |
|
55 | + // Catch the return/redirect from PayPal onboarding page. |
|
56 | + add_action('init', [__CLASS__, 'updateOnboardingStatus'], 10); |
|
57 | + // Return the connection/onboard status. |
|
58 | + add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']); |
|
59 | + // Revoke access. |
|
60 | + add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']); |
|
61 | + // Admin notice. |
|
62 | + add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
63 | + } |
|
64 | + } |
|
65 | + |
|
66 | + |
|
67 | + /** |
|
68 | + * Get the onboarding URL. |
|
69 | + * (AJAX) |
|
70 | + * |
|
71 | + * @return void |
|
72 | + */ |
|
73 | + public static function getOnboardingUrl(): void |
|
74 | + { |
|
75 | + $signup_link = ''; |
|
76 | + try { |
|
77 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
78 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
79 | + PayPalLogger::errorLogAndExit( |
|
80 | + esc_html__('No payment method.', 'event_espresso'), |
|
81 | + EED_Module::getRequest()->postParams(), |
|
82 | + $paypal_pm |
|
83 | + ); |
|
84 | + } |
|
85 | + PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams()); |
|
86 | + // $signup_link = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL); |
|
87 | + // $token_expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm); |
|
88 | + // if (! $signup_link || $token_expired) { |
|
89 | + $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm); |
|
90 | + // } |
|
91 | + if (! $signup_link) { |
|
92 | + $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso'); |
|
93 | + PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm); |
|
94 | + } |
|
95 | + PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL, $signup_link); |
|
96 | + } catch (Exception $exception) { |
|
97 | + PayPalLogger::errorLogAndExit($exception->getMessage()); |
|
98 | + } |
|
99 | + // Is it empty (can happen if we didn't get the URL through the API). |
|
100 | + $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#'; |
|
101 | + wp_send_json( |
|
102 | + [ |
|
103 | + 'signup_link' => $signup_link, |
|
104 | + ] |
|
105 | + ); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * Request the sign-up link from PayPal. |
|
111 | + * |
|
112 | + * @param EE_Payment_Method $paypal_pm |
|
113 | + * @param bool $one_time_request |
|
114 | + * @return string |
|
115 | + * @throws EE_Error |
|
116 | + * @throws Exception |
|
117 | + */ |
|
118 | + public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string |
|
119 | + { |
|
120 | + $signup_link = ''; |
|
121 | + // Get the access token. |
|
122 | + $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
123 | + if (! $access_token) { |
|
124 | + $err_msg = esc_html__('Error! No access token.', 'event_espresso'); |
|
125 | + PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm); |
|
126 | + return ''; |
|
127 | + } |
|
128 | + // Request the access token. |
|
129 | + $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm); |
|
130 | + $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
131 | + $post_params = [ |
|
132 | + 'method' => 'POST', |
|
133 | + 'headers' => [ |
|
134 | + 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
135 | + 'Content-Type' => 'application/json', |
|
136 | + 'Authorization' => 'Bearer ' . $access_token, |
|
137 | + 'PayPal-Partner-Attribution-Id' => $bn_code, |
|
138 | + ], |
|
139 | + 'body' => $body_params, |
|
140 | + ]; |
|
141 | + $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals'; |
|
142 | + $response = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params); |
|
143 | + // Check the data we received. |
|
144 | + if (isset($response['error']) || empty($response['links'])) { |
|
145 | + // Did the original access token get replaced by any chance ? |
|
146 | + if (! $one_time_request |
|
147 | + && ! empty($response['message']) |
|
148 | + && $response['message'] === 'Access Token not found in cache' |
|
149 | + ) { |
|
150 | + // Clear all PM metadata and try getting the access token One more time. |
|
151 | + PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
152 | + return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true); |
|
153 | + } |
|
154 | + $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso'); |
|
155 | + PayPalLogger::errorLog($err_msg, $response, $paypal_pm); |
|
156 | + return ''; |
|
157 | + } |
|
158 | + // Now retrieve that sign-up link. |
|
159 | + foreach ($response['links'] as $link) { |
|
160 | + if ($link['rel'] === 'action_url') { |
|
161 | + $signup_link = $link['href'] ?? ''; |
|
162 | + } |
|
163 | + } |
|
164 | + return $signup_link; |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + /** |
|
169 | + * Get the return URL. |
|
170 | + * |
|
171 | + * @param EE_Payment_Method $paypal_pm |
|
172 | + * @return string |
|
173 | + * @throws Exception |
|
174 | + */ |
|
175 | + public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string |
|
176 | + { |
|
177 | + $identifier_string = new OneTimeString($paypal_pm->debug_mode()); |
|
178 | + $tracking_id = $identifier_string->value(); |
|
179 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
180 | + $checkout_type = $request->getRequestParam('checkout_type', 'EXPRESS_CHECKOUT', DataType::STRING); |
|
181 | + // Save the identifier for future use. |
|
182 | + PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id); |
|
183 | + // Assemble the return URL. |
|
184 | + $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm); |
|
185 | + return json_encode([ |
|
186 | + 'tracking_id' => $tracking_id, |
|
187 | + 'operations' => [ |
|
188 | + [ |
|
189 | + 'operation' => 'API_INTEGRATION', |
|
190 | + 'api_integration_preference' => [ |
|
191 | + 'rest_api_integration' => [ |
|
192 | + 'integration_method' => 'PAYPAL', |
|
193 | + 'integration_type' => 'THIRD_PARTY', |
|
194 | + 'third_party_details' => [ |
|
195 | + 'features' => ['PAYMENT', 'REFUND'], |
|
196 | + ], |
|
197 | + ], |
|
198 | + ], |
|
199 | + ], |
|
200 | + ], |
|
201 | + 'products' => [$checkout_type], |
|
202 | + 'legal_consents' => [ |
|
203 | + [ |
|
204 | + 'type' => 'SHARE_DATA_CONSENT', |
|
205 | + 'granted' => true, |
|
206 | + ], |
|
207 | + ], |
|
208 | + 'partner_config_override' => [ |
|
209 | + 'return_url' => $return_url, |
|
210 | + ], |
|
211 | + ]); |
|
212 | + } |
|
213 | + |
|
214 | + |
|
215 | + /** |
|
216 | + * Get the return URL. |
|
217 | + * |
|
218 | + * @param EE_Payment_Method $paypal_pm |
|
219 | + * @return string |
|
220 | + * @throws EE_Error |
|
221 | + * @throws ReflectionException |
|
222 | + */ |
|
223 | + public static function getReturnUrl(EE_Payment_Method $paypal_pm): string |
|
224 | + { |
|
225 | + $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce'); |
|
226 | + $nonce = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN); |
|
227 | + return add_query_arg( |
|
228 | + [ |
|
229 | + 'page' => 'espresso_payment_settings', |
|
230 | + 'webhook_action' => 'eepPpcMerchantOnboard', |
|
231 | + 'payment_method' => $paypal_pm->slug(), |
|
232 | + '_wpnonce' => $wp_nonce, |
|
233 | + 'nonce' => $nonce, |
|
234 | + Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
235 | + ], |
|
236 | + admin_url('admin.php') |
|
237 | + ); |
|
238 | + } |
|
239 | + |
|
240 | + |
|
241 | + /** |
|
242 | + * Redirect to the payment method (PP) settings home page. |
|
243 | + * |
|
244 | + * @return void |
|
245 | + */ |
|
246 | + public static function redirectToPmSettingsHome(): void |
|
247 | + { |
|
248 | + $get_params = EED_Module::getRequest()->getParams(); |
|
249 | + if (empty($get_params['payment_method'])) { |
|
250 | + // Simply do not redirect. |
|
251 | + return; |
|
252 | + } |
|
253 | + $args_to_add = [ |
|
254 | + 'page' => 'espresso_payment_settings', |
|
255 | + 'payment_method' => $get_params['payment_method'], |
|
256 | + ]; |
|
257 | + if (isset($get_params['sandbox_mode'])) { |
|
258 | + $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode']; |
|
259 | + } |
|
260 | + $home_url = add_query_arg($args_to_add, admin_url('admin.php')); |
|
261 | + wp_redirect($home_url); |
|
262 | + exit; |
|
263 | + } |
|
264 | + |
|
265 | + |
|
266 | + /** |
|
267 | + * Check user’s onboarding status. |
|
268 | + * This will handle the user return from the auth page and also check the status via the API. |
|
269 | + * |
|
270 | + * @return void |
|
271 | + * @throws EE_Error |
|
272 | + * @throws ReflectionException |
|
273 | + */ |
|
274 | + public static function updateOnboardingStatus(): void |
|
275 | + { |
|
276 | + // Check if this is the webhook from PayPal. |
|
277 | + if (! isset($_GET['webhook_action'], $_GET['nonce']) |
|
278 | + || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard' |
|
279 | + ) { |
|
280 | + return; // Ignore. |
|
281 | + } |
|
282 | + $get_params = EED_Module::getRequest()->getParams(); |
|
283 | + // Get the payment method. |
|
284 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
285 | + // Check the response (GET) parameters. |
|
286 | + if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
287 | + // Missing parameters. Can't proceed. |
|
288 | + PayPalLogger::errorLog( |
|
289 | + esc_html__('Missing required onboarding parameters.', 'event_espresso'), |
|
290 | + $get_params, |
|
291 | + $paypal_pm |
|
292 | + ); |
|
293 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
294 | + return; |
|
295 | + } |
|
296 | + // Check on the onboarding status (recommended by PP). |
|
297 | + $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding( |
|
298 | + $paypal_pm, |
|
299 | + $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ] |
|
300 | + ); |
|
301 | + if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
302 | + PayPalLogger::errorLog( |
|
303 | + $onboarding_status['message'], |
|
304 | + array_merge($get_params, $onboarding_status), |
|
305 | + $paypal_pm |
|
306 | + ); |
|
307 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
308 | + return; |
|
309 | + } |
|
310 | + // Start saving the setup and info. |
|
311 | + PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status); |
|
312 | + // Save the credentials. |
|
313 | + PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params); |
|
314 | + // If onboarded successfully, remove the onboarding URL. |
|
315 | + PayPalExtraMetaManager::deletePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL); |
|
316 | + // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window. |
|
317 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
318 | + } |
|
319 | + |
|
320 | + |
|
321 | + /** |
|
322 | + * Check if all required parameters for the onboarding status check are present. |
|
323 | + * |
|
324 | + * @param array $data |
|
325 | + * @param mixed $paypal_pm |
|
326 | + * @return bool |
|
327 | + */ |
|
328 | + public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool |
|
329 | + { |
|
330 | + // Check that we have all the required parameters and the nonce is ok. |
|
331 | + if ($paypal_pm instanceof EE_Payment_Method |
|
332 | + && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN) |
|
333 | + && ! empty($data[ Domain::API_PARAM_PARTNER_ID ]) |
|
334 | + && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
335 | + && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ]) |
|
336 | + ) { |
|
337 | + return true; |
|
338 | + } |
|
339 | + return false; |
|
340 | + } |
|
341 | + |
|
342 | + |
|
343 | + /** |
|
344 | + * Get partner access token. |
|
345 | + * |
|
346 | + * @param EE_Payment_Method $paypal_pm |
|
347 | + * @return string |
|
348 | + * @throws EE_Error |
|
349 | + * @throws ReflectionException |
|
350 | + */ |
|
351 | + public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
352 | + { |
|
353 | + // Do we have it saved ? |
|
354 | + $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN); |
|
355 | + $expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm); |
|
356 | + // If we don't have it, request/update it. |
|
357 | + if (! $access_token || $expired) { |
|
358 | + return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
359 | + } |
|
360 | + // Access token is saved as encrypted, so return decrypted. |
|
361 | + return $access_token; |
|
362 | + } |
|
363 | + |
|
364 | + |
|
365 | + /** |
|
366 | + * Get partner access token. |
|
367 | + * |
|
368 | + * @param EE_Payment_Method $paypal_pm |
|
369 | + * @return bool |
|
370 | + */ |
|
371 | + public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool |
|
372 | + { |
|
373 | + $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_EXPIRES_IN); |
|
374 | + if (! $expires_at) { |
|
375 | + return true; |
|
376 | + } |
|
377 | + // Validate the token expiration date. |
|
378 | + $now = time(); |
|
379 | + $minutes_left = round(($expires_at - $now) / 60); |
|
380 | + // Count as expired if less than 60 minutes till expiration left. |
|
381 | + if ($minutes_left <= 60) { |
|
382 | + return true; |
|
383 | + } |
|
384 | + return false; |
|
385 | + } |
|
386 | + |
|
387 | + |
|
388 | + /** |
|
389 | + * Request the partner access token from PayPal and save/update it. |
|
390 | + * |
|
391 | + * @param EE_Payment_Method $paypal_pm |
|
392 | + * @return string |
|
393 | + * @throws EE_Error |
|
394 | + * @throws ReflectionException |
|
395 | + */ |
|
396 | + public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
397 | + { |
|
398 | + $nonce = wp_create_nonce('eea_pp_commerce_get_access_token'); |
|
399 | + // Request the access token. |
|
400 | + $post_args = [ |
|
401 | + 'method' => 'POST', |
|
402 | + 'body' => [ |
|
403 | + 'nonce' => $nonce, |
|
404 | + 'api_version' => 'v1', |
|
405 | + Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
406 | + ], |
|
407 | + ]; |
|
408 | + if (defined('LOCAL_MIDDLEMAN_SERVER')) { |
|
409 | + $post_args['sslverify'] = false; |
|
410 | + } |
|
411 | + $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token'; |
|
412 | + $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args); |
|
413 | + if (isset($response['error'])) { |
|
414 | + return ''; |
|
415 | + } |
|
416 | + // Check the data we received. |
|
417 | + if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
418 | + return ''; |
|
419 | + } |
|
420 | + // If we are here all seems to be ok. Save the token and it's data. |
|
421 | + $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response); |
|
422 | + if (! $saved) { |
|
423 | + return ''; |
|
424 | + } |
|
425 | + return $response['access_token']; |
|
426 | + } |
|
427 | + |
|
428 | + |
|
429 | + /** |
|
430 | + * Request seller onboarding status from PayPal. |
|
431 | + * |
|
432 | + * @param EE_Payment_Method $paypal_pm |
|
433 | + * @param string $merchant_id |
|
434 | + * @return array |
|
435 | + */ |
|
436 | + public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array |
|
437 | + { |
|
438 | + $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id); |
|
439 | + if (! $track_onboarding instanceof TrackSellerOnboarding) { |
|
440 | + $err_msg = esc_html__('Failed to track seller onboarding.', 'event_espresso'); |
|
441 | + return ['error' => 'TRACK_ONBOARDING_FAILED', 'message' => $err_msg]; |
|
442 | + } |
|
443 | + return $track_onboarding->isValid(); |
|
444 | + } |
|
445 | + |
|
446 | + |
|
447 | + /** |
|
448 | + * Returns the Track Seller Onboarding API. |
|
449 | + * |
|
450 | + * @param EE_Payment_Method $paypal_pm |
|
451 | + * @param string $merchant_id |
|
452 | + * @return TrackSellerOnboarding|null |
|
453 | + * @throws EE_Error |
|
454 | + * @throws ReflectionException |
|
455 | + */ |
|
456 | + public static function getTrackOnboardingApi( |
|
457 | + EE_Payment_Method $paypal_pm, |
|
458 | + string $merchant_id |
|
459 | + ): ?TrackSellerOnboarding { |
|
460 | + $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID); |
|
461 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
462 | + if (! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
463 | + return null; |
|
464 | + } |
|
465 | + return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode()); |
|
466 | + } |
|
467 | + |
|
468 | + |
|
469 | + /** |
|
470 | + * Check the onboard status and return the result. |
|
471 | + * (AJAX) |
|
472 | + * |
|
473 | + * @return void |
|
474 | + */ |
|
475 | + public static function getOnboardStatus(): void |
|
476 | + { |
|
477 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
478 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
479 | + $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso'); |
|
480 | + PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
481 | + wp_send_json(['on_board' => false]); |
|
482 | + } |
|
483 | + try { |
|
484 | + $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--'; |
|
485 | + } catch (Exception $e) { |
|
486 | + $seller_id = '--'; |
|
487 | + } |
|
488 | + wp_send_json( |
|
489 | + [ |
|
490 | + 'on_board' => EED_PayPalOnboard::isOnboard($paypal_pm), |
|
491 | + 'seller_id' => $seller_id, |
|
492 | + ] |
|
493 | + ); |
|
494 | + } |
|
495 | + |
|
496 | + |
|
497 | + /** |
|
498 | + * De-authorize the seller. Remove all API credentials. |
|
499 | + * (AJAX) |
|
500 | + * |
|
501 | + * @return void |
|
502 | + */ |
|
503 | + public static function offboard(): void |
|
504 | + { |
|
505 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
506 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
507 | + wp_send_json([ |
|
508 | + 'error' => 'INVALID_PM', |
|
509 | + 'message' => esc_html__( |
|
510 | + 'Invalid payment method. Please refresh the page and try again.', |
|
511 | + 'event_espresso' |
|
512 | + ), |
|
513 | + ]); |
|
514 | + } |
|
515 | + PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
516 | + wp_send_json(['success' => true]); |
|
517 | + } |
|
518 | + |
|
519 | + |
|
520 | + /** |
|
521 | + * Checks if already onboard. |
|
522 | + * |
|
523 | + * @param EE_Payment_Method $payment_method |
|
524 | + * @return boolean |
|
525 | + */ |
|
526 | + public static function isOnboard(EE_Payment_Method $payment_method): bool |
|
527 | + { |
|
528 | + $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method); |
|
529 | + return |
|
530 | + // onborded with a third party integration ? |
|
531 | + (! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
532 | + && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]) |
|
533 | + ) |
|
534 | + // or with the first party integration ? |
|
535 | + || (! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ]) |
|
536 | + && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ]) |
|
537 | + && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ]) |
|
538 | + ); |
|
539 | + } |
|
540 | + |
|
541 | + |
|
542 | + /** |
|
543 | + * Send a request and return a decoded response body. |
|
544 | + * |
|
545 | + * @param EE_Payment_Method $paypal_pm |
|
546 | + * @param string $request_url |
|
547 | + * @param array $request_args |
|
548 | + * @return array |
|
549 | + */ |
|
550 | + public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array |
|
551 | + { |
|
552 | + $error_return = ['error' => true]; |
|
553 | + $response = wp_remote_request($request_url, $request_args); |
|
554 | + if (is_wp_error($response)) { |
|
555 | + $message = $response->get_error_message(); |
|
556 | + PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
557 | + $error_return['message'] = $message; |
|
558 | + return $error_return; |
|
559 | + } |
|
560 | + $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : []; |
|
561 | + if (empty($response_body) || isset($response_body['error'])) { |
|
562 | + $message = $response_body['error_description'] |
|
563 | + ?? sprintf( |
|
564 | + esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'), |
|
565 | + $request_url |
|
566 | + ); |
|
567 | + PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
568 | + $error_return['message'] = $message; |
|
569 | + return $error_return; |
|
570 | + } |
|
571 | + return $response_body; |
|
572 | + } |
|
573 | + |
|
574 | + |
|
575 | + /** |
|
576 | + * Check the response for a partner token request. |
|
577 | + * |
|
578 | + * @param $response |
|
579 | + * @param EE_Payment_Method $paypal_pm |
|
580 | + * @return bool |
|
581 | + */ |
|
582 | + public static function partnerTokenResponseValid($response, EE_Payment_Method $paypal_pm): bool |
|
583 | + { |
|
584 | + // Check the data we received. |
|
585 | + if ( |
|
586 | + empty($response['nonce']) |
|
587 | + || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token') |
|
588 | + || empty($response['access_token']) |
|
589 | + || empty($response['app_id']) |
|
590 | + || empty($response['expires_in']) |
|
591 | + || empty($response['partner_client_id']) |
|
592 | + || empty($response['partner_merchant_id']) |
|
593 | + ) { |
|
594 | + // This is an error. |
|
595 | + $err_msg = esc_html__('Incoming parameter validation failed.', 'event_espresso'); |
|
596 | + PayPalLogger::errorLog($err_msg, (array) $response, $paypal_pm); |
|
597 | + return false; |
|
598 | + } |
|
599 | + return true; |
|
600 | + } |
|
601 | + |
|
602 | + |
|
603 | + /** |
|
604 | + * Returns the base URL to the middleman server. |
|
605 | + * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test |
|
606 | + * |
|
607 | + * @param EE_Payment_Method $payment_method |
|
608 | + * @return string |
|
609 | + * @throws EE_Error |
|
610 | + * @throws ReflectionException |
|
611 | + */ |
|
612 | + public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string |
|
613 | + { |
|
614 | + $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com'; |
|
615 | + // If this PM is used under different provider accounts, you might need an account indicator. |
|
616 | + $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : ''; |
|
617 | + $postfix = $payment_method->debug_mode() ? '_sandbox' : ''; |
|
618 | + $path = 'paypal_commerce' . $account . $postfix; |
|
619 | + return 'https://connect.eventespresso.' . $target . '/' . $path . '/'; |
|
620 | + } |
|
621 | + |
|
622 | + |
|
623 | + /** |
|
624 | + * This Payment Method admin notices. |
|
625 | + * |
|
626 | + * @return void |
|
627 | + * @throws EE_Error |
|
628 | + * @throws ReflectionException |
|
629 | + */ |
|
630 | + public static function adminNotice() |
|
631 | + { |
|
632 | + // Show the notice if PayPal Commerce PM is active but merchant is not onboard. |
|
633 | + $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
634 | + if ($pp_commerce instanceof EE_Payment_Method |
|
635 | + && $pp_commerce->active() |
|
636 | + && ! EED_PayPalOnboard::isOnboard($pp_commerce) |
|
637 | + ) { |
|
638 | + add_action('admin_notices', [__CLASS__, 'notOnboardNotice']); |
|
639 | + } |
|
640 | + } |
|
641 | + |
|
642 | + |
|
643 | + /** |
|
644 | + * Contents of the not onboard admin notice. |
|
645 | + * |
|
646 | + * @return void |
|
647 | + * @throws EE_Error |
|
648 | + * @throws ReflectionException |
|
649 | + */ |
|
650 | + public static function notOnboardNotice() |
|
651 | + { |
|
652 | + $open_anchor = $close_anchor = ''; |
|
653 | + $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
654 | + if ($pp_commerce instanceof EE_Payment_Method) { |
|
655 | + $pm_page = add_query_arg( |
|
656 | + [ |
|
657 | + 'page' => 'espresso_payment_settings', |
|
658 | + 'webhook_action' => 'eepPpcMerchantOnboard', |
|
659 | + 'payment_method' => $pp_commerce->slug(), |
|
660 | + ], |
|
661 | + admin_url('admin.php') |
|
662 | + ); |
|
663 | + $open_anchor = "<a href='$pm_page'>"; |
|
664 | + $close_anchor = "</a>"; |
|
665 | + } |
|
666 | + echo '<div class="error"><p>' |
|
667 | + . sprintf( |
|
668 | + esc_html__( |
|
669 | + '%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.', |
|
670 | + 'event_espresso' |
|
671 | + ), |
|
672 | + '<strong>', |
|
673 | + '</strong>', |
|
674 | + $open_anchor, |
|
675 | + $close_anchor |
|
676 | + ) |
|
677 | + . '</p></div>'; |
|
678 | + } |
|
679 | 679 | } |
@@ -75,7 +75,7 @@ discard block |
||
75 | 75 | $signup_link = ''; |
76 | 76 | try { |
77 | 77 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
78 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
78 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
79 | 79 | PayPalLogger::errorLogAndExit( |
80 | 80 | esc_html__('No payment method.', 'event_espresso'), |
81 | 81 | EED_Module::getRequest()->postParams(), |
@@ -88,7 +88,7 @@ discard block |
||
88 | 88 | // if (! $signup_link || $token_expired) { |
89 | 89 | $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm); |
90 | 90 | // } |
91 | - if (! $signup_link) { |
|
91 | + if ( ! $signup_link) { |
|
92 | 92 | $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso'); |
93 | 93 | PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm); |
94 | 94 | } |
@@ -97,7 +97,7 @@ discard block |
||
97 | 97 | PayPalLogger::errorLogAndExit($exception->getMessage()); |
98 | 98 | } |
99 | 99 | // Is it empty (can happen if we didn't get the URL through the API). |
100 | - $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#'; |
|
100 | + $signup_link = $signup_link ? $signup_link.'?&displayMode=minibrowser' : '#'; |
|
101 | 101 | wp_send_json( |
102 | 102 | [ |
103 | 103 | 'signup_link' => $signup_link, |
@@ -120,7 +120,7 @@ discard block |
||
120 | 120 | $signup_link = ''; |
121 | 121 | // Get the access token. |
122 | 122 | $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
123 | - if (! $access_token) { |
|
123 | + if ( ! $access_token) { |
|
124 | 124 | $err_msg = esc_html__('Error! No access token.', 'event_espresso'); |
125 | 125 | PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm); |
126 | 126 | return ''; |
@@ -133,17 +133,17 @@ discard block |
||
133 | 133 | 'headers' => [ |
134 | 134 | 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
135 | 135 | 'Content-Type' => 'application/json', |
136 | - 'Authorization' => 'Bearer ' . $access_token, |
|
136 | + 'Authorization' => 'Bearer '.$access_token, |
|
137 | 137 | 'PayPal-Partner-Attribution-Id' => $bn_code, |
138 | 138 | ], |
139 | 139 | 'body' => $body_params, |
140 | 140 | ]; |
141 | - $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals'; |
|
141 | + $request_url = Domain::getPayPalApiUrl($paypal_pm).'/v2/customer/partner-referrals'; |
|
142 | 142 | $response = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params); |
143 | 143 | // Check the data we received. |
144 | 144 | if (isset($response['error']) || empty($response['links'])) { |
145 | 145 | // Did the original access token get replaced by any chance ? |
146 | - if (! $one_time_request |
|
146 | + if ( ! $one_time_request |
|
147 | 147 | && ! empty($response['message']) |
148 | 148 | && $response['message'] === 'Access Token not found in cache' |
149 | 149 | ) { |
@@ -255,7 +255,7 @@ discard block |
||
255 | 255 | 'payment_method' => $get_params['payment_method'], |
256 | 256 | ]; |
257 | 257 | if (isset($get_params['sandbox_mode'])) { |
258 | - $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode']; |
|
258 | + $args_to_add[Domain::META_KEY_SANDBOX_MODE] = $get_params['sandbox_mode']; |
|
259 | 259 | } |
260 | 260 | $home_url = add_query_arg($args_to_add, admin_url('admin.php')); |
261 | 261 | wp_redirect($home_url); |
@@ -274,16 +274,16 @@ discard block |
||
274 | 274 | public static function updateOnboardingStatus(): void |
275 | 275 | { |
276 | 276 | // Check if this is the webhook from PayPal. |
277 | - if (! isset($_GET['webhook_action'], $_GET['nonce']) |
|
277 | + if ( ! isset($_GET['webhook_action'], $_GET['nonce']) |
|
278 | 278 | || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard' |
279 | 279 | ) { |
280 | - return; // Ignore. |
|
280 | + return; // Ignore. |
|
281 | 281 | } |
282 | 282 | $get_params = EED_Module::getRequest()->getParams(); |
283 | 283 | // Get the payment method. |
284 | 284 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
285 | 285 | // Check the response (GET) parameters. |
286 | - if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
286 | + if ( ! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
287 | 287 | // Missing parameters. Can't proceed. |
288 | 288 | PayPalLogger::errorLog( |
289 | 289 | esc_html__('Missing required onboarding parameters.', 'event_espresso'), |
@@ -296,9 +296,9 @@ discard block |
||
296 | 296 | // Check on the onboarding status (recommended by PP). |
297 | 297 | $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding( |
298 | 298 | $paypal_pm, |
299 | - $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ] |
|
299 | + $get_params[Domain::META_KEY_SELLER_MERCHANT_ID] |
|
300 | 300 | ); |
301 | - if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
301 | + if ( ! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
302 | 302 | PayPalLogger::errorLog( |
303 | 303 | $onboarding_status['message'], |
304 | 304 | array_merge($get_params, $onboarding_status), |
@@ -330,9 +330,9 @@ discard block |
||
330 | 330 | // Check that we have all the required parameters and the nonce is ok. |
331 | 331 | if ($paypal_pm instanceof EE_Payment_Method |
332 | 332 | && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN) |
333 | - && ! empty($data[ Domain::API_PARAM_PARTNER_ID ]) |
|
334 | - && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
335 | - && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ]) |
|
333 | + && ! empty($data[Domain::API_PARAM_PARTNER_ID]) |
|
334 | + && ! empty($data[Domain::META_KEY_SELLER_MERCHANT_ID]) |
|
335 | + && isset($data[Domain::API_PARAM_EMAIL_CONFIRMED]) |
|
336 | 336 | ) { |
337 | 337 | return true; |
338 | 338 | } |
@@ -354,7 +354,7 @@ discard block |
||
354 | 354 | $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN); |
355 | 355 | $expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm); |
356 | 356 | // If we don't have it, request/update it. |
357 | - if (! $access_token || $expired) { |
|
357 | + if ( ! $access_token || $expired) { |
|
358 | 358 | return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
359 | 359 | } |
360 | 360 | // Access token is saved as encrypted, so return decrypted. |
@@ -371,7 +371,7 @@ discard block |
||
371 | 371 | public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool |
372 | 372 | { |
373 | 373 | $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_EXPIRES_IN); |
374 | - if (! $expires_at) { |
|
374 | + if ( ! $expires_at) { |
|
375 | 375 | return true; |
376 | 376 | } |
377 | 377 | // Validate the token expiration date. |
@@ -408,18 +408,18 @@ discard block |
||
408 | 408 | if (defined('LOCAL_MIDDLEMAN_SERVER')) { |
409 | 409 | $post_args['sslverify'] = false; |
410 | 410 | } |
411 | - $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token'; |
|
411 | + $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm).'get_token'; |
|
412 | 412 | $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args); |
413 | 413 | if (isset($response['error'])) { |
414 | 414 | return ''; |
415 | 415 | } |
416 | 416 | // Check the data we received. |
417 | - if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
417 | + if ( ! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
418 | 418 | return ''; |
419 | 419 | } |
420 | 420 | // If we are here all seems to be ok. Save the token and it's data. |
421 | 421 | $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response); |
422 | - if (! $saved) { |
|
422 | + if ( ! $saved) { |
|
423 | 423 | return ''; |
424 | 424 | } |
425 | 425 | return $response['access_token']; |
@@ -436,7 +436,7 @@ discard block |
||
436 | 436 | public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array |
437 | 437 | { |
438 | 438 | $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id); |
439 | - if (! $track_onboarding instanceof TrackSellerOnboarding) { |
|
439 | + if ( ! $track_onboarding instanceof TrackSellerOnboarding) { |
|
440 | 440 | $err_msg = esc_html__('Failed to track seller onboarding.', 'event_espresso'); |
441 | 441 | return ['error' => 'TRACK_ONBOARDING_FAILED', 'message' => $err_msg]; |
442 | 442 | } |
@@ -459,7 +459,7 @@ discard block |
||
459 | 459 | ): ?TrackSellerOnboarding { |
460 | 460 | $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID); |
461 | 461 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
462 | - if (! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
462 | + if ( ! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
463 | 463 | return null; |
464 | 464 | } |
465 | 465 | return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode()); |
@@ -475,7 +475,7 @@ discard block |
||
475 | 475 | public static function getOnboardStatus(): void |
476 | 476 | { |
477 | 477 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
478 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
478 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
479 | 479 | $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso'); |
480 | 480 | PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm); |
481 | 481 | wp_send_json(['on_board' => false]); |
@@ -503,7 +503,7 @@ discard block |
||
503 | 503 | public static function offboard(): void |
504 | 504 | { |
505 | 505 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
506 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
506 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
507 | 507 | wp_send_json([ |
508 | 508 | 'error' => 'INVALID_PM', |
509 | 509 | 'message' => esc_html__( |
@@ -528,13 +528,13 @@ discard block |
||
528 | 528 | $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method); |
529 | 529 | return |
530 | 530 | // onborded with a third party integration ? |
531 | - (! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
532 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]) |
|
531 | + ( ! empty($pp_meta_data[Domain::META_KEY_SELLER_MERCHANT_ID]) |
|
532 | + && ! empty($pp_meta_data[Domain::META_KEY_ACCESS_TOKEN]) |
|
533 | 533 | ) |
534 | 534 | // or with the first party integration ? |
535 | - || (! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ]) |
|
536 | - && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ]) |
|
537 | - && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ]) |
|
535 | + || ( ! empty($pp_meta_data[Domain::META_KEY_CLIENT_ID]) |
|
536 | + && ! empty($pp_meta_data[Domain::META_KEY_CLIENT_SECRET]) |
|
537 | + && ! empty($pp_meta_data[Domain::META_KEY_PAYER_ID]) |
|
538 | 538 | ); |
539 | 539 | } |
540 | 540 | |
@@ -615,8 +615,8 @@ discard block |
||
615 | 615 | // If this PM is used under different provider accounts, you might need an account indicator. |
616 | 616 | $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : ''; |
617 | 617 | $postfix = $payment_method->debug_mode() ? '_sandbox' : ''; |
618 | - $path = 'paypal_commerce' . $account . $postfix; |
|
619 | - return 'https://connect.eventespresso.' . $target . '/' . $path . '/'; |
|
618 | + $path = 'paypal_commerce'.$account.$postfix; |
|
619 | + return 'https://connect.eventespresso.'.$target.'/'.$path.'/'; |
|
620 | 620 | } |
621 | 621 | |
622 | 622 |
@@ -22,290 +22,290 @@ |
||
22 | 22 | */ |
23 | 23 | class PayPalExtraMetaManager |
24 | 24 | { |
25 | - /** |
|
26 | - * Get payment method option/extra meta |
|
27 | - * |
|
28 | - * @param EE_Payment_Method $paypal_pm |
|
29 | - * @param string $option_name |
|
30 | - * @return mixed |
|
31 | - */ |
|
32 | - public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name) |
|
33 | - { |
|
34 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
35 | - $option_value = $pp_meta_data->getOption($option_name); |
|
36 | - // Decrypt the encrypted options. |
|
37 | - if ( |
|
38 | - $option_name === Domain::META_KEY_ACCESS_TOKEN |
|
39 | - || $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID |
|
40 | - || $option_name === Domain::META_KEY_CLIENT_SECRET |
|
41 | - ) { |
|
42 | - $option_value = self::decryptString($option_value, $paypal_pm); |
|
43 | - } |
|
44 | - return $option_value; |
|
45 | - } |
|
25 | + /** |
|
26 | + * Get payment method option/extra meta |
|
27 | + * |
|
28 | + * @param EE_Payment_Method $paypal_pm |
|
29 | + * @param string $option_name |
|
30 | + * @return mixed |
|
31 | + */ |
|
32 | + public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name) |
|
33 | + { |
|
34 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
35 | + $option_value = $pp_meta_data->getOption($option_name); |
|
36 | + // Decrypt the encrypted options. |
|
37 | + if ( |
|
38 | + $option_name === Domain::META_KEY_ACCESS_TOKEN |
|
39 | + || $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID |
|
40 | + || $option_name === Domain::META_KEY_CLIENT_SECRET |
|
41 | + ) { |
|
42 | + $option_value = self::decryptString($option_value, $paypal_pm); |
|
43 | + } |
|
44 | + return $option_value; |
|
45 | + } |
|
46 | 46 | |
47 | 47 | |
48 | - /** |
|
49 | - * Save payment method option/extra meta |
|
50 | - * |
|
51 | - * @param EE_Payment_Method $paypal_pm |
|
52 | - * @param string $option_name |
|
53 | - * @param $option_value |
|
54 | - * @return bool |
|
55 | - */ |
|
56 | - public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool |
|
57 | - { |
|
58 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
59 | - return $pp_meta_data->saveOption($option_name, $option_value); |
|
60 | - } |
|
48 | + /** |
|
49 | + * Save payment method option/extra meta |
|
50 | + * |
|
51 | + * @param EE_Payment_Method $paypal_pm |
|
52 | + * @param string $option_name |
|
53 | + * @param $option_value |
|
54 | + * @return bool |
|
55 | + */ |
|
56 | + public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool |
|
57 | + { |
|
58 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
59 | + return $pp_meta_data->saveOption($option_name, $option_value); |
|
60 | + } |
|
61 | 61 | |
62 | 62 | |
63 | - /** |
|
64 | - * Save a list of payment method options/extra meta. |
|
65 | - * |
|
66 | - * @param EE_Payment_Method $paypal_pm |
|
67 | - * @param array $options_list |
|
68 | - * @return bool |
|
69 | - */ |
|
70 | - public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool |
|
71 | - { |
|
72 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
73 | - return $pp_meta_data->saveBatch($options_list); |
|
74 | - } |
|
63 | + /** |
|
64 | + * Save a list of payment method options/extra meta. |
|
65 | + * |
|
66 | + * @param EE_Payment_Method $paypal_pm |
|
67 | + * @param array $options_list |
|
68 | + * @return bool |
|
69 | + */ |
|
70 | + public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool |
|
71 | + { |
|
72 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
73 | + return $pp_meta_data->saveBatch($options_list); |
|
74 | + } |
|
75 | 75 | |
76 | 76 | |
77 | - /** |
|
78 | - * Delete payment method option/extra meta |
|
79 | - * |
|
80 | - * @param EE_Payment_Method $paypal_pm |
|
81 | - * @param string $option_name |
|
82 | - * @return bool |
|
83 | - */ |
|
84 | - public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool |
|
85 | - { |
|
86 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
87 | - return $pp_meta_data->deleteOption($option_name); |
|
88 | - } |
|
77 | + /** |
|
78 | + * Delete payment method option/extra meta |
|
79 | + * |
|
80 | + * @param EE_Payment_Method $paypal_pm |
|
81 | + * @param string $option_name |
|
82 | + * @return bool |
|
83 | + */ |
|
84 | + public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool |
|
85 | + { |
|
86 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
87 | + return $pp_meta_data->deleteOption($option_name); |
|
88 | + } |
|
89 | 89 | |
90 | 90 | |
91 | - /** |
|
92 | - * Get all options for payment method. |
|
93 | - * |
|
94 | - * @param EE_Payment_Method $paypal_pm |
|
95 | - * @return array|bool |
|
96 | - */ |
|
97 | - public static function getAllData(EE_Payment_Method $paypal_pm) |
|
98 | - { |
|
99 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
100 | - return $pp_meta_data->getMetaData(); |
|
101 | - } |
|
91 | + /** |
|
92 | + * Get all options for payment method. |
|
93 | + * |
|
94 | + * @param EE_Payment_Method $paypal_pm |
|
95 | + * @return array|bool |
|
96 | + */ |
|
97 | + public static function getAllData(EE_Payment_Method $paypal_pm) |
|
98 | + { |
|
99 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
100 | + return $pp_meta_data->getMetaData(); |
|
101 | + } |
|
102 | 102 | |
103 | 103 | |
104 | - /** |
|
105 | - * Delete all options for this payment method. |
|
106 | - * |
|
107 | - * @param EE_Payment_Method $paypal_pm |
|
108 | - * @return bool |
|
109 | - */ |
|
110 | - public static function deleteAllData(EE_Payment_Method $paypal_pm): bool |
|
111 | - { |
|
112 | - $pp_meta_data = self::extraMeta($paypal_pm); |
|
113 | - return $pp_meta_data->deleteMetaData(); |
|
114 | - } |
|
104 | + /** |
|
105 | + * Delete all options for this payment method. |
|
106 | + * |
|
107 | + * @param EE_Payment_Method $paypal_pm |
|
108 | + * @return bool |
|
109 | + */ |
|
110 | + public static function deleteAllData(EE_Payment_Method $paypal_pm): bool |
|
111 | + { |
|
112 | + $pp_meta_data = self::extraMeta($paypal_pm); |
|
113 | + return $pp_meta_data->deleteMetaData(); |
|
114 | + } |
|
115 | 115 | |
116 | 116 | |
117 | - /** |
|
118 | - * Save the debug mode option if it changed. |
|
119 | - * |
|
120 | - * @param EE_Payment_Method $paypal_pm |
|
121 | - * @param array $request_data |
|
122 | - * @return bool Updated or not. |
|
123 | - */ |
|
124 | - public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool |
|
125 | - { |
|
126 | - if ( |
|
127 | - isset($request_data['sandbox_mode']) |
|
128 | - && in_array($request_data['sandbox_mode'], ['0', '1'], true) |
|
129 | - && $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode'] |
|
130 | - ) { |
|
131 | - try { |
|
132 | - $paypal_pm->save(['PMD_debug_mode' => $request_data['sandbox_mode']]); |
|
133 | - } catch (EE_Error $e) { |
|
134 | - $err_msg = sprintf( |
|
135 | - esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'), |
|
136 | - $e->getMessage() |
|
137 | - ); |
|
138 | - PayPalLogger::errorLog($err_msg, $request_data, $paypal_pm); |
|
139 | - return false; |
|
140 | - } |
|
141 | - return true; |
|
142 | - } |
|
143 | - return false; |
|
144 | - } |
|
117 | + /** |
|
118 | + * Save the debug mode option if it changed. |
|
119 | + * |
|
120 | + * @param EE_Payment_Method $paypal_pm |
|
121 | + * @param array $request_data |
|
122 | + * @return bool Updated or not. |
|
123 | + */ |
|
124 | + public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool |
|
125 | + { |
|
126 | + if ( |
|
127 | + isset($request_data['sandbox_mode']) |
|
128 | + && in_array($request_data['sandbox_mode'], ['0', '1'], true) |
|
129 | + && $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode'] |
|
130 | + ) { |
|
131 | + try { |
|
132 | + $paypal_pm->save(['PMD_debug_mode' => $request_data['sandbox_mode']]); |
|
133 | + } catch (EE_Error $e) { |
|
134 | + $err_msg = sprintf( |
|
135 | + esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'), |
|
136 | + $e->getMessage() |
|
137 | + ); |
|
138 | + PayPalLogger::errorLog($err_msg, $request_data, $paypal_pm); |
|
139 | + return false; |
|
140 | + } |
|
141 | + return true; |
|
142 | + } |
|
143 | + return false; |
|
144 | + } |
|
145 | 145 | |
146 | 146 | |
147 | - /** |
|
148 | - * Save partner access token and parameters. |
|
149 | - * |
|
150 | - * @param EE_Payment_Method $paypal_pm |
|
151 | - * @param array $response |
|
152 | - * @return bool |
|
153 | - */ |
|
154 | - public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool |
|
155 | - { |
|
156 | - $paypal_data = []; |
|
157 | - $expected_parameters = [ |
|
158 | - Domain::META_KEY_ACCESS_TOKEN, |
|
159 | - Domain::META_KEY_EXPIRES_IN, |
|
160 | - Domain::META_KEY_APP_ID, |
|
161 | - Domain::META_KEY_PARTNER_CLIENT_ID, |
|
162 | - Domain::META_KEY_PARTNER_MERCHANT_ID, |
|
163 | - Domain::META_KEY_BN_CODE, |
|
164 | - ]; |
|
165 | - foreach ($expected_parameters as $api_key) { |
|
166 | - if (! isset($response[ $api_key ])) { |
|
167 | - // Don't want to try saving data that doesn't exist. |
|
168 | - continue; |
|
169 | - } |
|
170 | - try { |
|
171 | - switch ($api_key) { |
|
172 | - case Domain::META_KEY_ACCESS_TOKEN: |
|
173 | - case Domain::META_KEY_PARTNER_MERCHANT_ID: |
|
174 | - $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm); |
|
175 | - break; |
|
176 | - case Domain::META_KEY_EXPIRES_IN: |
|
177 | - $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]); |
|
178 | - break; |
|
179 | - default: |
|
180 | - $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]); |
|
181 | - } |
|
182 | - } catch (Exception $exception) { |
|
183 | - PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm); |
|
184 | - return false; |
|
185 | - } |
|
186 | - } |
|
187 | - return self::savePmOptions($paypal_pm, $paypal_data); |
|
188 | - } |
|
147 | + /** |
|
148 | + * Save partner access token and parameters. |
|
149 | + * |
|
150 | + * @param EE_Payment_Method $paypal_pm |
|
151 | + * @param array $response |
|
152 | + * @return bool |
|
153 | + */ |
|
154 | + public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool |
|
155 | + { |
|
156 | + $paypal_data = []; |
|
157 | + $expected_parameters = [ |
|
158 | + Domain::META_KEY_ACCESS_TOKEN, |
|
159 | + Domain::META_KEY_EXPIRES_IN, |
|
160 | + Domain::META_KEY_APP_ID, |
|
161 | + Domain::META_KEY_PARTNER_CLIENT_ID, |
|
162 | + Domain::META_KEY_PARTNER_MERCHANT_ID, |
|
163 | + Domain::META_KEY_BN_CODE, |
|
164 | + ]; |
|
165 | + foreach ($expected_parameters as $api_key) { |
|
166 | + if (! isset($response[ $api_key ])) { |
|
167 | + // Don't want to try saving data that doesn't exist. |
|
168 | + continue; |
|
169 | + } |
|
170 | + try { |
|
171 | + switch ($api_key) { |
|
172 | + case Domain::META_KEY_ACCESS_TOKEN: |
|
173 | + case Domain::META_KEY_PARTNER_MERCHANT_ID: |
|
174 | + $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm); |
|
175 | + break; |
|
176 | + case Domain::META_KEY_EXPIRES_IN: |
|
177 | + $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]); |
|
178 | + break; |
|
179 | + default: |
|
180 | + $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]); |
|
181 | + } |
|
182 | + } catch (Exception $exception) { |
|
183 | + PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm); |
|
184 | + return false; |
|
185 | + } |
|
186 | + } |
|
187 | + return self::savePmOptions($paypal_pm, $paypal_data); |
|
188 | + } |
|
189 | 189 | |
190 | 190 | |
191 | - /** |
|
192 | - * Save merchant/seller API credentials. |
|
193 | - * |
|
194 | - * @param EE_Payment_Method $paypal_pm |
|
195 | - * @param array $response |
|
196 | - * @return bool |
|
197 | - */ |
|
198 | - public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool |
|
199 | - { |
|
200 | - $api_credentials = []; |
|
201 | - $expected_parameters = [ |
|
202 | - Domain::META_KEY_SELLER_MERCHANT_ID, |
|
203 | - ]; |
|
204 | - foreach ($expected_parameters as $api_key) { |
|
205 | - if (! isset($response[ $api_key ])) { |
|
206 | - // Don't want to try saving data that doesn't exist. |
|
207 | - continue; |
|
208 | - } |
|
209 | - $api_credentials[ $api_key ] = $response[ $api_key ]; |
|
210 | - } |
|
211 | - return self::savePmOptions($paypal_pm, $api_credentials); |
|
212 | - } |
|
191 | + /** |
|
192 | + * Save merchant/seller API credentials. |
|
193 | + * |
|
194 | + * @param EE_Payment_Method $paypal_pm |
|
195 | + * @param array $response |
|
196 | + * @return bool |
|
197 | + */ |
|
198 | + public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool |
|
199 | + { |
|
200 | + $api_credentials = []; |
|
201 | + $expected_parameters = [ |
|
202 | + Domain::META_KEY_SELLER_MERCHANT_ID, |
|
203 | + ]; |
|
204 | + foreach ($expected_parameters as $api_key) { |
|
205 | + if (! isset($response[ $api_key ])) { |
|
206 | + // Don't want to try saving data that doesn't exist. |
|
207 | + continue; |
|
208 | + } |
|
209 | + $api_credentials[ $api_key ] = $response[ $api_key ]; |
|
210 | + } |
|
211 | + return self::savePmOptions($paypal_pm, $api_credentials); |
|
212 | + } |
|
213 | 213 | |
214 | 214 | |
215 | - /** |
|
216 | - * Save other payment method related settings from a data array. |
|
217 | - * |
|
218 | - * @param EE_Payment_Method $paypal_pm |
|
219 | - * @param array $data |
|
220 | - * @return bool |
|
221 | - * @throws EE_Error |
|
222 | - * @throws ReflectionException |
|
223 | - */ |
|
224 | - public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data): bool |
|
225 | - { |
|
226 | - $allowed_checkout_type = 'express_checkout'; |
|
227 | - // Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only, |
|
228 | - // in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc. |
|
229 | - if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) { |
|
230 | - foreach ($data['response']['products'] as $product) { |
|
231 | - if (str_contains($product['name'], 'PPCP')) { |
|
232 | - // This merchant has PPCP in the products list, so we can enable both (all) checkout types. |
|
233 | - $allowed_checkout_type = 'all'; |
|
234 | - break; |
|
235 | - } |
|
236 | - } |
|
237 | - } |
|
238 | - // Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually. |
|
239 | - $checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false); |
|
240 | - if (! $checkout_type) { |
|
241 | - $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type); |
|
242 | - } |
|
243 | - return PayPalExtraMetaManager::savePmOption( |
|
244 | - $paypal_pm, |
|
245 | - Domain::META_KEY_ALLOWED_CHECKOUT_TYPE, |
|
246 | - $allowed_checkout_type |
|
247 | - ); |
|
248 | - } |
|
215 | + /** |
|
216 | + * Save other payment method related settings from a data array. |
|
217 | + * |
|
218 | + * @param EE_Payment_Method $paypal_pm |
|
219 | + * @param array $data |
|
220 | + * @return bool |
|
221 | + * @throws EE_Error |
|
222 | + * @throws ReflectionException |
|
223 | + */ |
|
224 | + public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data): bool |
|
225 | + { |
|
226 | + $allowed_checkout_type = 'express_checkout'; |
|
227 | + // Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only, |
|
228 | + // in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc. |
|
229 | + if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) { |
|
230 | + foreach ($data['response']['products'] as $product) { |
|
231 | + if (str_contains($product['name'], 'PPCP')) { |
|
232 | + // This merchant has PPCP in the products list, so we can enable both (all) checkout types. |
|
233 | + $allowed_checkout_type = 'all'; |
|
234 | + break; |
|
235 | + } |
|
236 | + } |
|
237 | + } |
|
238 | + // Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually. |
|
239 | + $checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false); |
|
240 | + if (! $checkout_type) { |
|
241 | + $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type); |
|
242 | + } |
|
243 | + return PayPalExtraMetaManager::savePmOption( |
|
244 | + $paypal_pm, |
|
245 | + Domain::META_KEY_ALLOWED_CHECKOUT_TYPE, |
|
246 | + $allowed_checkout_type |
|
247 | + ); |
|
248 | + } |
|
249 | 249 | |
250 | 250 | |
251 | - /** |
|
252 | - * Get PayPal extra meta helper. |
|
253 | - * |
|
254 | - * @param EE_Payment_Method $paypal_pm |
|
255 | - * @return PayPalExtraMeta |
|
256 | - */ |
|
257 | - public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta |
|
258 | - { |
|
259 | - return LoaderFactory::getLoader()->getShared(PayPalExtraMeta::class, [$paypal_pm]); |
|
260 | - } |
|
251 | + /** |
|
252 | + * Get PayPal extra meta helper. |
|
253 | + * |
|
254 | + * @param EE_Payment_Method $paypal_pm |
|
255 | + * @return PayPalExtraMeta |
|
256 | + */ |
|
257 | + public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta |
|
258 | + { |
|
259 | + return LoaderFactory::getLoader()->getShared(PayPalExtraMeta::class, [$paypal_pm]); |
|
260 | + } |
|
261 | 261 | |
262 | 262 | |
263 | - /** |
|
264 | - * Encrypt a text field. |
|
265 | - * |
|
266 | - * @param string $text |
|
267 | - * @param EE_Payment_Method $paypal_pm |
|
268 | - * @return string|null |
|
269 | - */ |
|
270 | - public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string |
|
271 | - { |
|
272 | - // We sure we are getting something ? |
|
273 | - if (! $text) { |
|
274 | - return $text; |
|
275 | - } |
|
276 | - // Do encrypt. |
|
277 | - $encryptor = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]); |
|
278 | - $sanitized_text = sanitize_text_field($text); |
|
279 | - $key_identifier = $paypal_pm->debug_mode() |
|
280 | - ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID |
|
281 | - : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID; |
|
282 | - return $encryptor->encrypt($sanitized_text, $key_identifier); |
|
283 | - } |
|
263 | + /** |
|
264 | + * Encrypt a text field. |
|
265 | + * |
|
266 | + * @param string $text |
|
267 | + * @param EE_Payment_Method $paypal_pm |
|
268 | + * @return string|null |
|
269 | + */ |
|
270 | + public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string |
|
271 | + { |
|
272 | + // We sure we are getting something ? |
|
273 | + if (! $text) { |
|
274 | + return $text; |
|
275 | + } |
|
276 | + // Do encrypt. |
|
277 | + $encryptor = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]); |
|
278 | + $sanitized_text = sanitize_text_field($text); |
|
279 | + $key_identifier = $paypal_pm->debug_mode() |
|
280 | + ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID |
|
281 | + : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID; |
|
282 | + return $encryptor->encrypt($sanitized_text, $key_identifier); |
|
283 | + } |
|
284 | 284 | |
285 | 285 | |
286 | - /** |
|
287 | - * Decrypt a string. |
|
288 | - * |
|
289 | - * @param string $text |
|
290 | - * @param EE_Payment_Method $paypal_pm |
|
291 | - * @return string |
|
292 | - */ |
|
293 | - public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string |
|
294 | - { |
|
295 | - // Are we even getting something ? |
|
296 | - if (! $text) { |
|
297 | - return $text; |
|
298 | - } |
|
299 | - // Try decrypting. |
|
300 | - try { |
|
301 | - $encryptor = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]); |
|
302 | - $key_identifier = $paypal_pm->debug_mode() |
|
303 | - ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID |
|
304 | - : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID; |
|
305 | - $decrypted = $encryptor->decrypt($text, $key_identifier); |
|
306 | - } catch (Exception $e) { |
|
307 | - return $text; |
|
308 | - } |
|
309 | - return $decrypted ?? $text; |
|
310 | - } |
|
286 | + /** |
|
287 | + * Decrypt a string. |
|
288 | + * |
|
289 | + * @param string $text |
|
290 | + * @param EE_Payment_Method $paypal_pm |
|
291 | + * @return string |
|
292 | + */ |
|
293 | + public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string |
|
294 | + { |
|
295 | + // Are we even getting something ? |
|
296 | + if (! $text) { |
|
297 | + return $text; |
|
298 | + } |
|
299 | + // Try decrypting. |
|
300 | + try { |
|
301 | + $encryptor = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]); |
|
302 | + $key_identifier = $paypal_pm->debug_mode() |
|
303 | + ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID |
|
304 | + : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID; |
|
305 | + $decrypted = $encryptor->decrypt($text, $key_identifier); |
|
306 | + } catch (Exception $e) { |
|
307 | + return $text; |
|
308 | + } |
|
309 | + return $decrypted ?? $text; |
|
310 | + } |
|
311 | 311 | } |
@@ -163,7 +163,7 @@ discard block |
||
163 | 163 | Domain::META_KEY_BN_CODE, |
164 | 164 | ]; |
165 | 165 | foreach ($expected_parameters as $api_key) { |
166 | - if (! isset($response[ $api_key ])) { |
|
166 | + if ( ! isset($response[$api_key])) { |
|
167 | 167 | // Don't want to try saving data that doesn't exist. |
168 | 168 | continue; |
169 | 169 | } |
@@ -171,13 +171,13 @@ discard block |
||
171 | 171 | switch ($api_key) { |
172 | 172 | case Domain::META_KEY_ACCESS_TOKEN: |
173 | 173 | case Domain::META_KEY_PARTNER_MERCHANT_ID: |
174 | - $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm); |
|
174 | + $paypal_data[$api_key] = self::encryptString($response[$api_key], $paypal_pm); |
|
175 | 175 | break; |
176 | 176 | case Domain::META_KEY_EXPIRES_IN: |
177 | - $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]); |
|
177 | + $paypal_data[$api_key] = time() + (int) sanitize_key($response[$api_key]); |
|
178 | 178 | break; |
179 | 179 | default: |
180 | - $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]); |
|
180 | + $paypal_data[$api_key] = sanitize_text_field($response[$api_key]); |
|
181 | 181 | } |
182 | 182 | } catch (Exception $exception) { |
183 | 183 | PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm); |
@@ -202,11 +202,11 @@ discard block |
||
202 | 202 | Domain::META_KEY_SELLER_MERCHANT_ID, |
203 | 203 | ]; |
204 | 204 | foreach ($expected_parameters as $api_key) { |
205 | - if (! isset($response[ $api_key ])) { |
|
205 | + if ( ! isset($response[$api_key])) { |
|
206 | 206 | // Don't want to try saving data that doesn't exist. |
207 | 207 | continue; |
208 | 208 | } |
209 | - $api_credentials[ $api_key ] = $response[ $api_key ]; |
|
209 | + $api_credentials[$api_key] = $response[$api_key]; |
|
210 | 210 | } |
211 | 211 | return self::savePmOptions($paypal_pm, $api_credentials); |
212 | 212 | } |
@@ -226,7 +226,7 @@ discard block |
||
226 | 226 | $allowed_checkout_type = 'express_checkout'; |
227 | 227 | // Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only, |
228 | 228 | // in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc. |
229 | - if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) { |
|
229 | + if ( ! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) { |
|
230 | 230 | foreach ($data['response']['products'] as $product) { |
231 | 231 | if (str_contains($product['name'], 'PPCP')) { |
232 | 232 | // This merchant has PPCP in the products list, so we can enable both (all) checkout types. |
@@ -237,7 +237,7 @@ discard block |
||
237 | 237 | } |
238 | 238 | // Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually. |
239 | 239 | $checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false); |
240 | - if (! $checkout_type) { |
|
240 | + if ( ! $checkout_type) { |
|
241 | 241 | $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type); |
242 | 242 | } |
243 | 243 | return PayPalExtraMetaManager::savePmOption( |
@@ -270,7 +270,7 @@ discard block |
||
270 | 270 | public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string |
271 | 271 | { |
272 | 272 | // We sure we are getting something ? |
273 | - if (! $text) { |
|
273 | + if ( ! $text) { |
|
274 | 274 | return $text; |
275 | 275 | } |
276 | 276 | // Do encrypt. |
@@ -293,7 +293,7 @@ discard block |
||
293 | 293 | public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string |
294 | 294 | { |
295 | 295 | // Are we even getting something ? |
296 | - if (! $text) { |
|
296 | + if ( ! $text) { |
|
297 | 297 | return $text; |
298 | 298 | } |
299 | 299 | // Try decrypting. |