Automattic\WooCommerce\Gateways\PayPal
Request::authorize_or_capture_payment
Authorize or capture a PayPal payment using the Orders v2 API.
This method authorizes or captures a PayPal payment and updates the order status.
Method of the class: Request{}
No Hooks.
Returns
null. Nothing (null).
Usage
$Request = new Request(); $Request->authorize_or_capture_payment( ?WC_Order $order, ?string $action_url, $action, $is_retry ): void;
- ?WC_Order $order(required)
- .
- ?string $action_url(required)
- .
- $action(string)
- The action to perform. Either
'authorize'or'capture'.
Default:PayPalConstants::PAYMENT_ACTION_CAPTURE - $is_retry(true|false)
- Whether the payment is being retried.
Default:false
Request::authorize_or_capture_payment() Request::authorize or capture payment code WC 10.8.1
public function authorize_or_capture_payment( ?WC_Order $order, ?string $action_url, string $action = PayPalConstants::PAYMENT_ACTION_CAPTURE, bool $is_retry = false ): void {
if ( ! $order ) {
\WC_Gateway_Paypal::log( 'Order not found to authorize or capture payment.' );
return;
}
$paypal_debug_id = null;
$paypal_order_id = $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_ORDER_ID );
if ( ! $paypal_order_id ) {
\WC_Gateway_Paypal::log( 'PayPal order ID not found. Cannot ' . $action . ' payment.' );
return;
}
if ( ! $action_url || ! filter_var( $action_url, FILTER_VALIDATE_URL ) ) {
\WC_Gateway_Paypal::log( 'Invalid or missing action URL. Cannot ' . $action . ' payment.' );
return;
}
// Skip if the payment is already captured.
if ( PayPalConstants::STATUS_COMPLETED === $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_STATUS, true ) ) {
\WC_Gateway_Paypal::log( 'PayPal payment is already captured. Skipping capture. Order ID: ' . $order->get_id() );
return;
}
try {
if ( PayPalConstants::PAYMENT_ACTION_CAPTURE === $action ) {
$endpoint = self::WPCOM_PROXY_PAYMENT_CAPTURE_ENDPOINT;
$request_body = array(
'capture_url' => $action_url,
'paypal_order_id' => $paypal_order_id,
'test_mode' => $this->gateway->testmode,
);
} else {
$endpoint = self::WPCOM_PROXY_PAYMENT_AUTHORIZE_ENDPOINT;
$request_body = array(
'authorize_url' => $action_url,
'paypal_order_id' => $paypal_order_id,
'test_mode' => $this->gateway->testmode,
);
}
$response = $this->send_wpcom_proxy_request( 'POST', $endpoint, $request_body );
if ( is_wp_error( $response ) ) {
throw new Exception( 'PayPal ' . $action . ' payment request failed. Response error: ' . $response->get_error_message() );
}
$http_code = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );
$response_data = json_decode( $body, true );
$issue = isset( $response_data['details'][0]['issue'] ) ? $response_data['details'][0]['issue'] : '';
$duplicate_invoice_id = 422 === $http_code && PayPalConstants::PAYPAL_ISSUE_DUPLICATE_INVOICE_ID === $issue;
// If the payment failed with a duplicate invoice ID error and it's not a retry, handle it.
// If it's a retry, don't handle it again.
if ( $duplicate_invoice_id && ! $is_retry ) {
$this->handle_duplicate_invoice_id( $order, $paypal_order_id, $action_url, $action );
return;
}
if ( 200 !== $http_code && 201 !== $http_code ) {
$paypal_debug_id = isset( $response_data['debug_id'] ) ? $response_data['debug_id'] : null;
throw new Exception( 'PayPal ' . $action . ' payment failed. Response status: ' . $http_code . '. Response body: ' . $body );
}
} catch ( Exception $e ) {
\WC_Gateway_Paypal::log( $e->getMessage() );
$note_message = sprintf(
/* translators: %1$s: Action, %2$s: PayPal order ID */
__( 'PayPal %1$s payment failed. PayPal Order ID: %2$s', 'woocommerce' ),
$action,
$paypal_order_id
);
// Add debug ID to the note if available.
if ( $paypal_debug_id ) {
$note_message .= sprintf(
/* translators: %s: PayPal debug ID */
__( '. PayPal debug ID: %s', 'woocommerce' ),
$paypal_debug_id
);
}
$order->add_order_note( $note_message );
$order->update_status( OrderStatus::FAILED );
$order->save();
}
}