Failed Conditions
Push — develop ( 2de1b1...49fae7 )
by Remco
12:57 queued 04:10
created

Gateway   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 587
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 16
Bugs 0 Features 0
Metric Value
eloc 205
c 16
b 0
f 0
dl 0
loc 587
ccs 0
cts 275
cp 0
rs 8.8
wmc 45

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
B get_issuers() 0 25 7
A get_supported_payment_methods() 0 9 1
B update_status() 0 55 9
C request() 0 123 10
F start() 0 304 17

How to fix   Complexity   

Complex Class

Complex classes like Gateway often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Gateway, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\Buckaroo;
4
5
use Pronamic\WordPress\Money\Money;
6
use Pronamic\WordPress\Pay\Banks\BankAccountDetails;
7
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
8
use Pronamic\WordPress\Pay\Core\PaymentMethods as Core_PaymentMethods;
9
use Pronamic\WordPress\Pay\Core\Server;
10
use Pronamic\WordPress\Pay\Payments\Payment;
11
12
/**
13
 * Title: Buckaroo gateway
14
 * Description:
15
 * Copyright: 2005-2021 Pronamic
16
 * Company: Pronamic
17
 *
18
 * @author Remco Tolsma
19
 * @version 2.0.4
20
 * @since 1.0.0
21
 */
22
class Gateway extends Core_Gateway {
23
	/**
24
	 * Client.
0 ignored issues
show
Bug introduced by
The type Pronamic\WordPress\Pay\Gateways\Buckaroo\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
	 *
26
	 * @var Client
27
	 */
28
	protected $client;
29
30
	/**
31
	 * Constructs and initializes an Buckaroo gateway
32
	 *
33
	 * @param Config $config Config.
34
	 */
35
	public function __construct( Config $config ) {
36
		parent::__construct( $config );
37
38
		$this->set_method( self::METHOD_HTTP_REDIRECT );
39
40
		// Supported features.
41
		$this->supports = array(
42
			'payment_status_request',
43
			'refunds',
44
			'webhook',
45
			'webhook_log',
46
			'webhook_no_config',
47
		);
48
	}
49
50
	/**
51
	 * Get issuers.
52
	 *
53
	 * @since 1.2.4
54
	 * @see Pronamic_WP_Pay_Gateway::get_issuers()
55
	 */
56
	public function get_issuers() {
57
		$groups = array();
58
59
		$object = $this->request( 'GET', 'Transaction/Specification/ideal?serviceVersion=2' );
60
61
		foreach ( $object->Actions as $action ) {
62
			if ( 'Pay' === $action->Name ) {
63
				foreach ( $action->RequestParameters as $request_parameter ) {
64
					if ( 'issuer' === $request_parameter->Name ) {
65
						foreach ( $request_parameter->ListItemDescriptions as $item ) {
66
							if ( ! array_key_exists( $item->GroupName, $groups ) ) {
67
								$groups[ $item->GroupName ] = array(
68
									'name'    => $item->GroupName,
69
									'options' => array(),
70
								);
71
							}
72
73
							$groups[ $item->GroupName ]['options'][ $item->Value ] = $item->Description;
74
						}
75
					}
76
				}
77
			}
78
		}
79
80
		return $groups;
81
	}
82
83
	/**
84
	 * Get supported payment methods
85
	 *
86
	 * @see Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
87
	 */
88
	public function get_supported_payment_methods() {
89
		return array(
90
			Core_PaymentMethods::BANK_TRANSFER,
91
			Core_PaymentMethods::BANCONTACT,
92
			Core_PaymentMethods::CREDIT_CARD,
93
			Core_PaymentMethods::GIROPAY,
94
			Core_PaymentMethods::IDEAL,
95
			Core_PaymentMethods::PAYPAL,
96
			Core_PaymentMethods::SOFORT,
97
		);
98
	}
99
100
	/**
101
	 * Start
102
	 *
103
	 * @param Payment $payment Payment.
104
	 *
105
	 * @see Core_Gateway::start()
106
	 */
107
	public function start( Payment $payment ) {
108
		/**
109
		 * Currency.
110
		 */
111
		$currency_code = $payment->get_total_amount()->get_currency()->get_alphabetic_code();
112
113
		if ( null === $currency_code ) {
114
			throw new \InvalidArgumentException( 'Can not start payment with empty currency code.' );
115
		}
116
117
		/**
118
		 * Push URL.
119
		 */
120
		$push_url = \rest_url( Integration::REST_ROUTE_NAMESPACE . '/push' );
121
122
		/**
123
		 * Filters the Buckaroo push URL.
124
		 *
125
		 * If you want to debug the Buckaroo report URL you can use this filter
126
		 * to override the push URL. You could for example use a service like
127
		 * https://webhook.site/ to inspect the push requests from Buckaroo.
128
		 *
129
		 * @param string $push_url Buckaroo push URL.
130
		 */
131
		$push_url = \apply_filters( 'pronamic_pay_buckaroo_push_url', $push_url );
132
133
		/**
134
		 * JSON Transaction.
135
		 *
136
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
137
		 */
138
		$data = (object) array(
139
			'Currency'                  => $currency_code,
140
			'AmountDebit'               => $payment->get_total_amount()->get_value(),
141
			'Invoice'                   => Util::get_invoice_number( (string) $this->config->get_invoice_number(), $payment ),
142
			'ReturnURL'                 => $payment->get_return_url(),
143
			'ReturnURLCancel'           => \add_query_arg(
144
				'buckaroo_return_url_cancel',
145
				true,
146
				$payment->get_return_url()
147
			),
148
			'ReturnURLError'            => \add_query_arg(
149
				'buckaroo_return_url_error',
150
				true,
151
				$payment->get_return_url()
152
			),
153
			'ReturnURLReject'           => \add_query_arg(
154
				'buckaroo_return_url_reject',
155
				true,
156
				$payment->get_return_url()
157
			),
158
			/**
159
			 * Push URL.
160
			 *
161
			 * When provided, this push URL overrides all the push URLs as configured in the payment plaza under websites for the associated website key
162
			 *
163
			 * @link https://dev.buckaroo.nl/Apis
164
			 */
165
			'PushURL'                   => $push_url,
166
			/**
167
			 * Push URL Failure.
168
			 *
169
			 * When provided, this push URL overrides the push URL for failed transactions as configured in the payment plaza under websites for the associated website key.
170
			 *
171
			 * @link https://dev.buckaroo.nl/Apis
172
			 */
173
			'PushURLFailure'            => $push_url,
174
			/**
175
			 * Services.
176
			 *
177
			 * Specifies which service (can be a payment method and/or additional service) is being called upon in the request.
178
			 *
179
			 * @link https://dev.buckaroo.nl/Apis
180
			 */
181
			'Services'                  => (object) array(
182
				'ServiceList' => array(),
183
			),
184
			/**
185
			 * Continue On Incomplete.
186
			 *
187
			 * Specifies if a redirecturl to a payment form will be returned to
188
			 * which a customer should be sent if no paymentmethod is selected
189
			 * or if any required parameter which the customer may provide is
190
			 * missing or incorrect. Possible Values:
191
			 *
192
			 * · No: This is the default. The request will fail if not all the
193
			 * needed information is provided.
194
			 *
195
			 * · RedirectToHTML: A redirect to the HTML gateway is provided if
196
			 * a recoverable problems are detected in the request. The customer
197
			 * can then provide the needed information there.
198
			 *
199
			 * @link https://dev.buckaroo.nl/Apis
200
			 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
201
			 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=ContinueOnIncomplete
202
			 */
203
			'ContinueOnIncomplete'      => 'RedirectToHTML',
204
			/**
205
			 * Services Excluded For Client.
206
			 *
207
			 * If no primary service is provided and ContinueOnIncomplete is
208
			 * set, this list of comma separated servicescodes can be used to
209
			 * limit the number of services from which the customer may choose
210
			 * once he is redirected to the payment form. Services which are
211
			 * entered in this field are not selectable.
212
			 * This field is optional.
213
			 *
214
			 * @link https://dev.buckaroo.nl/Apis
215
			 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
216
			 */
217
			'ServicesExcludedForClient' => $this->config->get_excluded_services(),
218
			/**
219
			 * Custom parameters.
220
			 *
221
			 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
222
			 */
223
			'CustomParameters'          => array(
224
				(object) array(
225
					'Name'  => 'pronamic_payment_id',
226
					'Value' => $payment->get_id(),
227
				),
228
			),
229
		);
230
231
		/**
232
		 * Client IP.
233
		 *
234
		 * In this field the IP address of the customer (or employee) for which
235
		 * the action is being performed can be passed. Please note, If this
236
		 * field is not sent to our gateway, your server IP address will be
237
		 * used as the clientIP. This may result in unwanted behaviour for
238
		 * anti-fraud checks. Also, certain payment methods perform checks on
239
		 * the IP address, if an IP address is overused, the request could be
240
		 * blocked. This field is sent in the following format, where
241
		 * type 0 = IPv4 and type 1 = IPv6:
242
		 * "ClientIP": { "Type": 0, "Address": "0.0.0.0" },
243
		 *
244
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
245
		 * @link https://stackoverflow.com/questions/1448871/how-to-know-which-version-of-the-internet-protocol-ip-a-client-is-using-when-c/1448901
246
		 */
247
		$customer = $payment->get_customer();
248
249
		if ( null !== $customer ) {
250
			$ip_address = $customer->get_ip_address();
251
252
			if ( null !== $ip_address ) {
253
				$data->ClientIP = (object) array(
254
					'Type'    => false === \strpos( $ip_address, ':' ) ? 0 : 1,
255
					'Address' => $ip_address,
256
				);
257
			}
258
		}
259
260
		/**
261
		 * Payment method.
262
		 *
263
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
264
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=ServicesRequest
265
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=ServiceRequest
266
		 */
267
		$payment_method = $payment->get_method();
268
269
		switch ( $payment_method ) {
270
			/**
271
			 * Payment method creditcard.
272
			 *
273
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/creditcards#pay
274
			 */
275
			case Core_PaymentMethods::CREDIT_CARD:
276
				$data->Services->ServiceList[] = (object) array(
277
					'Action' => 'Pay',
278
					'Name'   => PaymentMethods::AMERICAN_EXPRESS,
279
				);
280
281
				$data->Services->ServiceList[] = (object) array(
282
					'Action' => 'Pay',
283
					'Name'   => PaymentMethods::MAESTRO,
284
				);
285
286
				$data->Services->ServiceList[] = (object) array(
287
					'Action' => 'Pay',
288
					'Name'   => PaymentMethods::MASTERCARD,
289
				);
290
291
				$data->Services->ServiceList[] = (object) array(
292
					'Action' => 'Pay',
293
					'Name'   => PaymentMethods::VISA,
294
				);
295
296
				break;
297
			/**
298
			 * Payment method iDEAL.
299
			 *
300
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/ideal#pay
301
			 */
302
			case Core_PaymentMethods::IDEAL:
303
				$data->Services->ServiceList[] = (object) array(
304
					'Action'     => 'Pay',
305
					'Name'       => 'ideal',
306
					'Parameters' => array(
307
						array(
308
							'Name'  => 'issuer',
309
							'Value' => $payment->get_issuer(),
310
						),
311
					),
312
				);
313
314
				break;
315
			/**
316
			 * Payment method transfer.
317
			 *
318
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/transfer#pay
319
			 */
320
			case Core_PaymentMethods::BANK_TRANSFER:
321
				$data->Services->ServiceList[] = (object) array(
322
					'Action' => 'Pay',
323
					'Name'   => 'transfer',
324
				);
325
326
				break;
327
			/**
328
			 * Payment method Bancontact.
329
			 *
330
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/bancontact#pay
331
			 */
332
			case Core_PaymentMethods::BANCONTACT:
333
			case Core_PaymentMethods::MISTER_CASH:
0 ignored issues
show
Deprecated Code introduced by
The constant Pronamic\WordPress\Pay\C...entMethods::MISTER_CASH has been deprecated: "Bancontact/Mister Cash" was renamed to just "Bancontact". ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

333
			case /** @scrutinizer ignore-deprecated */ Core_PaymentMethods::MISTER_CASH:

This class constant has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.

Loading history...
334
				$data->Services->ServiceList[] = (object) array(
335
					'Action' => 'Pay',
336
					'Name'   => 'bancontactmrcash',
337
				);
338
339
				break;
340
			/**
341
			 * Payment method Giropay.
342
			 *
343
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/giropay#pay
344
			 */
345
			case Core_PaymentMethods::GIROPAY:
346
				$data->Services->ServiceList[] = (object) array(
347
					'Action' => 'Pay',
348
					'Name'   => 'giropay',
349
				);
350
351
				break;
352
			/**
353
			 * Payment method PayPal.
354
			 *
355
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/paypal#pay
356
			 */
357
			case Core_PaymentMethods::PAYPAL:
358
				$data->Services->ServiceList[] = (object) array(
359
					'Action' => 'Pay',
360
					'Name'   => 'paypal',
361
				);
362
363
				break;
364
			/**
365
			 * Payment method Sofort.
366
			 *
367
			 * @link https://dev.buckaroo.nl/PaymentMethods/Description/sofort#pay
368
			 */
369
			case Core_PaymentMethods::SOFORT:
370
				$data->Services->ServiceList[] = (object) array(
371
					'Action' => 'Pay',
372
					'Name'   => 'sofortueberweisung',
373
				);
374
375
				break;
376
		}
377
378
		/**
379
		 * Request.
380
		 */
381
		$object = $this->request( 'POST', 'Transaction', $data );
382
383
		if ( 'Redirect' !== $object->RequiredAction->Name ) {
384
			throw new \Exception(
385
				\sprintf(
386
					'Unsupported Buckaroo action: %s',
387
					$object->RequiredAction->Name
388
				)
389
			);
390
		}
391
392
		$payment->set_action_url( $object->RequiredAction->RedirectURL );
393
394
		/**
395
		 * Buckaroo keys.
396
		 *
397
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionResponse
398
		 */
399
		$payment->set_meta( 'buckaroo_transaction_key', $object->Key );
400
		$payment->set_meta( 'buckaroo_transaction_payment_key', $object->PaymentKey );
401
402
		/**
403
		 * Transaction ID.
404
		 *
405
		 * @link https://dev.buckaroo.nl/PaymentMethods/Description/ideal]
406
		 */
407
		foreach ( $object->Services as $service ) {
408
			foreach ( $service->Parameters as $parameter ) {
409
				if ( 'transactionId' === $parameter->Name ) {
410
					$payment->set_transaction_id( $parameter->Value );
411
				}
412
			}
413
		}
414
	}
415
416
	/**
417
	 * JSON API Request.
418
	 *
419
	 * @param string      $method   HTTP request method.
420
	 * @param string      $endpoint JSON API endpoint.
421
	 * @param object|null $data     Data.
422
	 */
423
	private function request( $method, $endpoint, $data = null ) {
424
		$host = 'checkout.buckaroo.nl';
425
426
		if ( self::MODE_TEST === $this->config->mode ) {
427
			$host = 'testcheckout.buckaroo.nl';
428
		}
429
430
		/**
431
		 * Authentication.
432
		 *
433
		 * The HMAC SHA256 is calculated over a concatenated string (as raw data/binary/bytes) of the following values: WebsiteKey, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String. See the next table for more information about these values. Please note: the Base64 hash should be a string of 44 characters. If yours is longer, it is probably in hexadecimal format.
434
		 *
435
		 * @link https://dev.buckaroo.nl/Apis/Description/json
436
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Authentication
437
		 */
438
		$website_key         = $this->config->website_key;
439
		$request_http_method = $method;
440
		$request_uri         = $host . '/json/' . $endpoint;
441
		$request_timestamp   = \strval( \time() );
442
		$nonce               = \wp_generate_password( 32 );
443
		$request_content     = null === $data ? '' : \wp_json_encode( $data );
444
445
		$values = \implode(
446
			'',
447
			array(
448
				$website_key,
449
				$request_http_method,
450
				\strtolower( \rawurlencode( $request_uri ) ),
451
				$request_timestamp,
452
				$nonce,
453
				\
454
				// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
455
				null === $data ? '' : \base64_encode( \md5( $request_content, true ) ),
0 ignored issues
show
Bug introduced by
It seems like $request_content can also be of type false; however, parameter $string of md5() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

455
				null === $data ? '' : \base64_encode( \md5( /** @scrutinizer ignore-type */ $request_content, true ) ),
Loading history...
456
			)
457
		);
458
459
		$hash = \hash_hmac( 'sha256', $values, $this->config->secret_key, true );
460
461
		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
462
		$hmac = \base64_encode( $hash );
463
464
		$authorization = \sprintf(
465
			'hmac %s:%s:%s:%s',
466
			$this->config->website_key,
467
			$hmac,
468
			$nonce,
469
			$request_timestamp
470
		);
471
472
		$response = \Pronamic\WordPress\Http\Facades\Http::request(
473
			'https://' . $request_uri,
474
			array(
475
				'method'  => $request_http_method,
476
				'headers' => array(
477
					'Authorization' => $authorization,
478
					'Content-Type'  => 'application/json',
479
				),
480
				'body'    => $request_content,
481
			)
482
		);
483
484
		$object = $response->json();
485
486
		/**
487
		 * Request Errors.
488
		 *
489
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/POST-json-Transaction
490
		 */
491
		$exception = null;
492
493
		/**
494
		 * Channel errors.
495
		 *
496
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionRequestResponseChannelError
497
		 */
498
		foreach ( $object->RequestErrors->ChannelErrors as $error ) {
499
			$exception = new \Exception( $error->ErrorMessage, 0, $exception );
500
		}
501
502
		/**
503
		 * Service errors.
504
		 *
505
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionRequestResponseServiceError
506
		 */
507
		foreach ( $object->RequestErrors->ServiceErrors as $error ) {
508
			$exception = new \Exception( $error->ErrorMessage, 0, $exception );
509
		}
510
511
		/**
512
		 * Action errors.
513
		 *
514
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionRequestResponseActionError
515
		 */
516
		foreach ( $object->RequestErrors->ActionErrors as $error ) {
517
			$exception = new \Exception( $error->ErrorMessage, 0, $exception );
518
		}
519
520
		/**
521
		 * Action errors.
522
		 *
523
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionRequestResponseParameterError
524
		 */
525
		foreach ( $object->RequestErrors->ParameterErrors as $error ) {
526
			$exception = new \Exception( $error->ErrorMessage, 0, $exception );
527
		}
528
529
		/**
530
		 * Action errors.
531
		 *
532
		 * @link https://testcheckout.buckaroo.nl/json/Docs/ResourceModel?modelName=TransactionRequestResponseCustomParameterError
533
		 */
534
		foreach ( $object->RequestErrors->CustomParameterErrors as $error ) {
535
			$exception = new \Exception( $error->ErrorMessage, 0, $exception );
536
		}
537
538
		if ( null !== $exception ) {
539
			throw $exception;
540
		}
541
542
		/**
543
		 * OK.
544
		 */
545
		return $object;
546
	}
547
548
	/**
549
	 * Update status of the specified payment
550
	 *
551
	 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/GET-json-Transaction-Status-transactionKey
552
	 * @param Payment $payment Payment.
553
	 */
554
	public function update_status( Payment $payment ) {
555
		$transaction_key = $payment->get_meta( 'buckaroo_transaction_key' );
556
557
		if ( empty( $transaction_key ) ) {
558
			return;
559
		}
560
561
		$result = $this->request( 'GET', 'Transaction/Status/' . $transaction_key );
562
563
		$payment->set_status( Statuses::transform( \strval( $result->Status->Code->Code ) ) );
564
565
		/**
566
		 * Consumer bank details.
567
		 */
568
		$consumer_bank_details = $payment->get_consumer_bank_details();
569
570
		if ( null === $consumer_bank_details ) {
571
			$consumer_bank_details = new BankAccountDetails();
572
573
			$payment->set_consumer_bank_details( $consumer_bank_details );
574
		}
575
576
		/**
577
		 * Services.
578
		 */
579
		foreach ( $result->Services as $service ) {
580
			foreach ( $service->Parameters as $parameter ) {
581
				if ( 'transactionId' === $parameter->Name ) {
582
					$payment->set_transaction_id( $parameter->Value );
583
				}
584
585
				if ( 'consumerName' === $parameter->Name ) {
586
					$consumer_bank_details->set_name( $parameter->Value );
587
				}
588
589
				if ( 'consumerIBAN' === $parameter->Name ) {
590
					$consumer_bank_details->set_iban( $parameter->Value );
591
				}
592
593
				if ( 'consumerBIC' === $parameter->Name ) {
594
					$consumer_bank_details->set_iban( $parameter->Value );
595
				}
596
			}
597
		}
598
599
		/**
600
		 * Refunds.
601
		 *
602
		 * @link https://testcheckout.buckaroo.nl/json/Docs/Api/GET-json-Transaction-RefundInfo-transactionKey
603
		 */
604
		$result = $this->request( 'GET', 'Transaction/RefundInfo/' . $transaction_key );
605
606
		$refunded_amount = new Money( $result->RefundedAmount, $result->RefundCurrency );
607
608
		$payment->set_refunded_amount( $refunded_amount );
609
	}
610
}
611