Automattic\WooCommerce\Gateways\PayPal
Request::create_paypal_order
Create a PayPal order using the Orders v2 API.
This method creates a PayPal order and returns the order details including the approval URL where customers will be redirected to complete payment.
Method of the class: Request{}
Hooks from the method
Returns
Array|null.
Usage
$Request = new Request(); $Request->create_paypal_order( $order, $payment_source, $js_sdk_params ): ?array;
- $order(WC_Order) (required)
- Order object.
- $payment_source(string)
- The payment source.
Default:PayPalConstants::PAYMENT_SOURCE_PAYPAL - $js_sdk_params(array)
- Extra parameters for a PayPal JS SDK (Buttons) request.
Default:array()
Request::create_paypal_order() Request::create paypal order code WC 10.7.0
public function create_paypal_order(
WC_Order $order,
string $payment_source = PayPalConstants::PAYMENT_SOURCE_PAYPAL,
array $js_sdk_params = array()
): ?array {
$paypal_debug_id = null;
// While PayPal JS SDK can return 'paylater' as the payment source in the createOrder callback,
// Orders v2 API does not accept it. We will use 'paypal' instead.
// Accepted payment_source values for Orders v2:
// https://developer.paypal.com/docs/api/orders/v2/#orders_create!ct=application/json&path=payment_source&t=request.
if ( PayPalConstants::PAYMENT_SOURCE_PAYLATER === $payment_source ) {
$payment_source = PayPalConstants::PAYMENT_SOURCE_PAYPAL;
}
try {
$request_body = array(
'test_mode' => $this->gateway->testmode,
'order' => $this->get_paypal_create_order_request_params( $order, $payment_source, $js_sdk_params ),
);
$response = $this->send_wpcom_proxy_request( 'POST', self::WPCOM_PROXY_ORDER_ENDPOINT, $request_body );
if ( is_wp_error( $response ) ) {
throw new Exception( 'PayPal order creation failed. Response error: ' . $response->get_error_message() );
}
if ( ! is_array( $response ) ) {
throw new Exception( 'PayPal order creation failed. Invalid response type.' );
}
$http_code = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );
$response_data = json_decode( $body, true );
$response_array = is_array( $response_data ) ? $response_data : array();
/**
* Fires after receiving a response from PayPal order creation.
*
* This hook allows extensions to react to PayPal API responses, such as
* displaying admin notices or logging response data.
*
* Note: This hook fires on EVERY order creation attempt (success or failure),
* and can be called multiple times for the same order if retried. Extensions
* hooking this should be idempotent and check order state/meta before taking
* action to avoid duplicate processing.
*
* @since 10.4.0
*
* @param int|string $http_code The HTTP status code from the PayPal API response.
* @param array $response_data The decoded response data from the PayPal API
* @param WC_Order $order The WooCommerce order object.
*/
do_action( 'woocommerce_paypal_standard_order_created_response', $http_code, $response_array, $order );
if ( ! in_array( $http_code, array( 200, 201 ), true ) ) {
$paypal_debug_id = isset( $response_data['debug_id'] ) ? $response_data['debug_id'] : null;
throw new Exception( 'PayPal order creation failed. Response status: ' . $http_code . '. Response body: ' . $body );
}
$redirect_url = null;
if ( empty( $js_sdk_params['is_js_sdk_flow'] ) ) {
// We only need an approve link for the classic, redirect flow.
$redirect_url = $this->get_approve_link( $http_code, $response_data );
if ( empty( $redirect_url ) ) {
throw new Exception( 'PayPal order creation failed. Missing approval link.' );
}
}
// Save the PayPal order ID to the order.
$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_ORDER_ID, $response_data['id'] );
// Save the PayPal order status to the order.
$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_STATUS, $response_data['status'] );
// Remember the payment source: payment_source is not patchable.
// If the payment source is changed, we need to create a new PayPal order.
$order->update_meta_data( PayPalConstants::PAYPAL_ORDER_META_PAYMENT_SOURCE, $payment_source );
$order->save();
return array(
'id' => $response_data['id'],
'redirect_url' => $redirect_url,
);
} catch ( Exception $e ) {
\WC_Gateway_Paypal::log( $e->getMessage() );
if ( $paypal_debug_id ) {
$order->add_order_note(
sprintf(
/* translators: %1$s: PayPal debug ID */
__( 'PayPal order creation failed. PayPal debug ID: %1$s', 'woocommerce' ),
$paypal_debug_id
)
);
}
return null;
}
}