Automattic\WooCommerce\Gateways\PayPal
Request::handle_duplicate_invoice_id
Handle duplicate invoice ID. This is a workaround to handle the duplicate invoice ID error that occurs when the invoice ID is not unique. We generate a new invoice ID and patch the invoice ID in the PayPal order. Then we retry capturing the payment.
Method of the class: Request{}
No Hooks.
Returns
null. Nothing (null).
Usage
// private - for code of main (parent) class only $result = $this->handle_duplicate_invoice_id( $order, $paypal_order_id, $action_url, $action ): void;
- $order(WC_Order) (required)
- Order object.
- $paypal_order_id(string) (required)
- The PayPal order ID.
- $action_url(string) (required)
- The action URL.
- $action(string) (required)
- The action.
Request::handle_duplicate_invoice_id() Request::handle duplicate invoice id code WC 10.7.0
private function handle_duplicate_invoice_id( WC_Order $order, string $paypal_order_id, string $action_url, string $action ): void {
$new_invoice_id = $this->generate_paypal_invoice_id_with_unique_suffix( $order );
\WC_Gateway_Paypal::log( 'Attempting to patch PayPal order invoice_id. PayPal Order ID: ' . $paypal_order_id . '. New invoice_id: ' . $new_invoice_id . '. Order ID: ' . $order->get_id() );
try {
$request_body = array(
'test_mode' => $this->gateway->testmode,
'order' => array(
array(
'op' => 'replace',
'path' => "/purchase_units/@reference_id=='default'/invoice_id",
'value' => $new_invoice_id,
),
),
);
$response = $this->send_wpcom_proxy_request( 'PATCH', self::WPCOM_PROXY_ORDER_ENDPOINT . '/' . $paypal_order_id, $request_body );
if ( is_wp_error( $response ) ) {
throw new Exception( 'PayPal patch invoice_id 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 );
if ( 200 !== $http_code && 204 !== $http_code ) {
\WC_Gateway_Paypal::log( 'PayPal patch invoice_id failed. Response status: ' . $http_code . '. Response body: ' . $body );
throw new Exception( 'Failed to patch PayPal order invoice_id. Response status: ' . $http_code );
}
\WC_Gateway_Paypal::log( 'Successfully patched PayPal order invoice_id. PayPal Order ID: ' . $paypal_order_id . '. New invoice_id: ' . $new_invoice_id . '. Order ID: ' . $order->get_id() );
$order->add_order_note(
sprintf(
/* translators: %1$s: New invoice ID */
__( 'PayPal order Invoice ID updated to %1$s to ensure uniqueness.', 'woocommerce' ),
esc_html( $new_invoice_id )
)
);
$order->save();
// Retry authorizing or capturing the payment after patching the invoice_id.
$this->authorize_or_capture_payment( $order, $action_url, $action, true );
} catch ( Exception $e ) {
\WC_Gateway_Paypal::log( $e->getMessage() );
// phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
throw new Exception( $e->getMessage() );
}
}