Automattic\WooCommerce\Gateways\PayPal
Request::capture_authorized_payment │ public │ WC 1.0
Capture a PayPal payment that has been authorized.
Method of the class: Request{}
No Hooks.
Returns
null. Nothing (null).
Usage
$Request = new Request(); $Request->capture_authorized_payment( ?WC_Order $order ): void;
- ?WC_Order $order(required)
- .
Request::capture_authorized_payment() Request::capture authorized payment code WC 10.7.0
public function capture_authorized_payment( ?WC_Order $order ): void {
if ( ! $order ) {
\WC_Gateway_Paypal::log( 'Order not found to capture authorized payment.' );
return;
}
$paypal_order_id = $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_ORDER_ID, true );
// Skip if the PayPal Order ID is not found. This means the order was not created via the Orders v2 API.
if ( ! $paypal_order_id ) {
\WC_Gateway_Paypal::log( 'PayPal Order ID not found to capture authorized payment. Order ID: ' . $order->get_id() );
return;
}
$capture_id = $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_CAPTURE_ID, true );
// Skip if the payment is already captured.
if ( $capture_id ) {
\WC_Gateway_Paypal::log( 'PayPal payment is already captured. PayPal capture ID: ' . $capture_id . '. Order ID: ' . $order->get_id() );
return;
}
$paypal_status = $order->get_meta( PayPalConstants::PAYPAL_ORDER_META_STATUS, true );
// Skip if the payment is already captured.
if ( PayPalConstants::STATUS_CAPTURED === $paypal_status || PayPalConstants::STATUS_COMPLETED === $paypal_status ) {
\WC_Gateway_Paypal::log( 'PayPal payment is already captured. Skipping capture. Order ID: ' . $order->get_id() );
return;
}
// Skip if the payment requires payer action.
if ( PayPalConstants::STATUS_PAYER_ACTION_REQUIRED === $paypal_status ) {
\WC_Gateway_Paypal::log( 'PayPal payment requires payer action. Skipping capture. Order ID: ' . $order->get_id() );
return;
}
// Skip if the payment is voided.
if ( PayPalConstants::VOIDED === $paypal_status ) {
\WC_Gateway_Paypal::log( 'PayPal payment voided. Skipping capture. Order ID: ' . $order->get_id() );
return;
}
$authorization_id = $this->get_authorization_id_for_capture( $order );
if ( ! $authorization_id ) {
\WC_Gateway_Paypal::log( 'Authorization ID not found to capture authorized payment. Order ID: ' . $order->get_id() );
return;
}
$paypal_debug_id = null;
$http_code = null;
try {
$request_body = array(
'test_mode' => $this->gateway->testmode,
'authorization_id' => $authorization_id,
'paypal_order_id' => $paypal_order_id,
);
$response = $this->send_wpcom_proxy_request( 'POST', self::WPCOM_PROXY_PAYMENT_CAPTURE_AUTH_ENDPOINT, $request_body );
if ( is_wp_error( $response ) ) {
throw new Exception( 'PayPal capture 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'] : '';
$auth_already_captured = 422 === $http_code && PayPalConstants::PAYPAL_ISSUE_AUTHORIZATION_ALREADY_CAPTURED === $issue;
if ( 200 !== $http_code && 201 !== $http_code && ! $auth_already_captured ) {
$paypal_debug_id = isset( $response_data['debug_id'] ) ? $response_data['debug_id'] : null;
throw new Exception( 'PayPal capture payment failed. Response status: ' . $http_code . '. Response body: ' . $body );
}
// Set custom status for successful capture response, or if the authorization was already captured.
$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_STATUS, PayPalConstants::STATUS_CAPTURED );
$order->save();
} catch ( Exception $e ) {
\WC_Gateway_Paypal::log( $e->getMessage() );
$note_message = sprintf(
__( 'PayPal capture authorized payment failed', 'woocommerce' ),
);
// Scenario 1: Capture auth API call returned 404 (authorization object does not exist).
// If the authorization ID is not found (404 response), set the '_paypal_authorization_checked' flag.
// This flag indicates that we've made an API call to capture PayPal payment and no authorization object was found with this authorization ID.
// This prevents repeated API calls for orders that have no authorization data.
if ( 404 === $http_code ) {
$paypal_dashboard_url = $this->gateway->testmode
? 'https://www.sandbox.paypal.com/unifiedtransactions'
: 'https://www.paypal.com/unifiedtransactions';
$note_message .= sprintf(
/* translators: %1$s: Authorization ID, %2$s: open link tag, %3$s: close link tag */
__( '. Authorization ID: %1$s not found. Please log into your %2$sPayPal account%3$s to capture the payment', 'woocommerce' ),
esc_html( $authorization_id ),
'<a href="' . esc_url( $paypal_dashboard_url ) . '" target="_blank">',
'</a>'
);
$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_AUTHORIZATION_CHECKED, 'yes' );
}
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->save();
}
}