2015-06-18 12 views
5

Utilizzando lo WooCommerce REST API v2, sto creando un ordine in uno stato in sospeso e non pagato.API REST di WooCommerce v2: come elaborare il pagamento?

Posso vedere che posso impostare il campo order.payment_details.paid su true che creerà l'ordine in uno stato completato e invierà un'e-mail di ordine completato, ma in realtà non elabora il pagamento.

Qual è il modo corretto di utilizzare l'API REST v2 per creare un ordine e WooCommerce elaborare il pagamento utilizzando il gateway di pagamento?

Oppure è necessario aggiungere un hook di plugin all'API sul lato server? (Credo di sì)

Ecco che cosa ho provato

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 
       } 
      ] 
      } 
     }' 

, che, come ho detto, genera un ordine in stato completato, ma in realtà non elaborare qualsiasi soldi con il mio ingresso (che non è "StackOverflow Money Laundering, Inc." ed è un gateway legittimo che funziona quando si utilizza il nostro sito WooCommerce)

+1

Non credo che sia possibile elaborare un pagamento tramite l'API. Almeno guardando i [documenti API] (http://woothemes.github.io/woocommerce-rest-api-docs/) non vedo una sezione per l'elaborazione del pagamento. – helgatheviking

risposta

6

Come helgatheviking consentito, attualmente non esiste un modo per elaborare il pagamento di un ordine con l'API REST di WooCommerce.

Ho finito per scrivere un hook nel filtro woocommerce_api_create_order che elabora immediatamente l'ordine per il pagamento quando viene creato l'ordine. Se l'elaborazione fallisce, gli errori vengono aggiunti al campo order->post->post_excerpt che lo fa apparire come order->note nella risposta JSON.

Perché ciò funzioni, ho anche dovuto estendere il gateway di pagamento in modo che il suo metodo process_payment() accetti un $user_id come input. Questo perché è codificato fuori dagli schemi per operare sull'utente attualmente connesso, il che, nel mio caso e probabilmente nella maggior parte dei casi, è l'utente di sistema che il client REST accede come, non l'utente reale che effettua un acquisto.

L'altro vantaggio dell'estensione del gateway è che ora è possibile restituire gli errori anziché scrivere su wc_add_notice(). Dal momento che questo è un servizio REST, nulla vede mai l'uscita di 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) 
       ); 
     } 
    } 
} 
3

Grazie per la direzione che mi hai dato.

Ho apportato alcune modifiche e passaggi semplificati.

come segue:

add_filter('woocommerce_api_order_response', 'intercept_api_response', 1, 4); 
/** 
* Here, intercept api's 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; 
} 

Spero che questo possa aiutare qualcun altro. È stato un duro lavoro con molte prove ed errori.

+0

Come fare il pagamento usando questo plugin [WooCommerce PayPal Alimentato da Braintree Payment Gateway] (https://wordpress.org/plugins/woocommerce-gateway-paypal-powered-by-braintree/) via WooCommerce API REST –

+0

Questa versione omette il passaggio critico di estendere il gateway e passare un ID utente nella chiamata al metodo di pagamento di processo corretta? come in: function process_payment ($ order_id, $ user_id), La risposta accettata ha funzionato per me. – claytronicon

Problemi correlati