WooCommerce REST API v2: how to process payment?

Using the WooCommerce REST API v2 , I successfully create an order in a pending, unpaid state.

I see that I can set the order.payment_details.paid field to true , which will create the order in the completed state and send the completed order email address, but will not actually process the payment.

How can I use the REST API v2 to create an order and execute the WooCommerce process using a payment gateway?

Or do I need to add a plugin to the server side API? (I think so)

Here is what I tried

 curl -X POST https://example.com/wc-api/v2/orders \ -u consumer_key:consumer_secret \ -H "Content-Type: application/json" \ -d '{ "order": { "customer_id": 2, "payment_details": { "method_id": "da_big_bank", "method_title": "StackOverflow Money Laundering, Inc.", "paid":true }, "line_items": [ { "product_id": 341, "quantity": 1 } ] } }' 

which, as I said, generates an order in a completed state, but actually does not process any money using my gateway (which is not "StackOverflow Money Laundering, Inc." and is a legitimate gateway that works when using our WooCommerce)

+5
source share
2 answers

Since helgatheviking agrees, there is currently no way to process payment for an order using the WooCommerce REST API.

I ended up writing a hook in the woocommerce_api_create_order filter, which immediately processes the payment order when creating an order. If the processing failed, then errors are added to the order->post->post_excerpt , which makes it appear as order->note in the JSON response.

To do this, I also had to expand the payment gateway so that its process_payment() method $user_id as input. This is due to the fact that it is encoded out of the box for working with the current user, who in my case and, probably, in most cases is a system user, which includes the REST client, and not the actual user making the purchase.

Another advantage of the expansion of the gateway was that now errors can be returned rather than written to wc_add_notice() . Since this is a REST service, nothing ever sees the output of wc_add_notice()

 add_filter('woocommerce_api_create_order', 'acme_on_api_create_order', 10, 3); /** * When order is created in REST client, actually make them pay for it * @param int $id order id * @param array $data order data posted by client * @param WC_API_Orders $api not used * @return array the data passed back unaltered */ function acme_on_api_create_order($id, $data, $api) { if($data['payment_details']['method_id'] == 'acme_rest_gateway') { $order = wc_get_order($id); $order->calculate_totals(); $acme_gateway = new WC_Acme_Gateway_For_Rest(); $payment = $acme_gateway->process_payment($id, $data['customer_id']); if($payment["result"] == "success") { $order->update_status('completed'); } else { $order->update_status("cancelled"); wp_update_post(array( 'ID' => $id, 'post_excerpt' => json_encode($payment) )); } } return $data; } // Register the payment gateway add_filter('woocommerce_payment_gateways', 'acme_add_payment_gateway_class'); function acme_add_payment_gateway_class($methods) { $methods[] = 'WC_Acme_Gateway_For_Rest'; return $methods; } // Load the new payment gateway needed by REST client add_action('after_setup_theme', 'acme_init_rest_gateway_class'); function acme_init_rest_gateway_class() { /** * Extend the payment gateway to work in the REST API context */ class WC_Acme_Gateway_For_Rest extends WC_Acme_Gateway { /** * Constructor for the gateway. */ public function __construct() { parent::__construct(); $this->id = 'acme_rest_gateway'; } /** * Process Payment. This is the same as the parent::process_payment($order_id) except that we're also passing * the user id rather than reading get_current_user_id(). * And we're returning errors rather than writing them as notices * @param int $order_id the order id * @param int $user_id user id * @return array|null an array if success. otherwise returns nothing */ function process_payment($order_id, $user_id) { $order = wc_get_order( $order_id ); /* * todo: code sending da moneez to da bank */ return array( 'result' => 'success', 'redirect' => $this->get_return_url( $order ) ); } } } 
+6
source

Thank you for the direction you gave me.

I made some changes and simplified steps.

Properly:

 add_filter('woocommerce_api_order_response', 'intercept_api_response', 1, 4); /** * Here, intercept api response to include the url of payment **/ function intercept_api_response($order_data, $order) { $order_data['payment_url'] = $order->payment_url; return $order_data; } add_filter('woocommerce_api_create_order', 'intercept_on_api_create_order', 10, 3); function intercept_on_api_create_order($id, $data, $api) { if (in_array($data['payment_details']['method_id'], ['pagseguro', 'paypal'])) { $order = wc_get_order($id); $order->calculate_totals(); if ($data['payment_details']['method_id'] == 'paypal') { $paypal = new WC_Gateway_Paypal(); $payment = $paypal->process_payment($id); } update_post_meta($id, '_payment_url', $payment['redirect']); } return $payment; } 

Hope this helps someone else. It was hard work with lots of trial and error.

+3
source

All Articles