WooCommerce REST API v2:如何处理付款?

Posted

技术标签:

【中文标题】WooCommerce REST API v2:如何处理付款?【英文标题】:WooCommerce REST API v2: How to process payment? 【发布时间】:2015-09-04 12:39:52 【问题描述】:

使用WooCommerce REST API v2,我成功地创建了一个处于待处理、未付款状态的订单。

我可以看到我可以将order.payment_details.paid 字段设置为true,这将创建处于已完成状态的订单并发送已完成的订单电子邮件,但它实际上并不处理付款。

使用 REST API v2 创建订单并让 WooCommerce 使用支付网关处理支付的正确方法是什么?

或者我需要在服务器端的 API 中添加插件挂钩吗? (我想是的)

这是我尝试过的

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": "*** Money Laundering, Inc.",
              "paid":true
            ,
            "line_items": [
              
                "product_id": 341,
                "quantity": 1
              
            ]
          
        '

正如我所说,它会生成一个已完成状态的订单,但实际上并没有使用我的网关处理任何资金(它不是“*** Money Laundering, Inc.”,并且是一个合法的网关,在使用我们的WooCommerce 网站)

【问题讨论】:

我不相信您可以通过 API 处理付款。至少,看看API docs,我没有看到处理付款的部分。 【参考方案1】:

正如helgatheviking 同意的那样,目前没有办法使用 WooCommerce REST API 处理订单付款。

我最终在woocommerce_api_create_order 过滤器中编写了一个挂钩,该过滤器在创建订单时立即处理付款订单。如果处理失败,则会将错误添加到 order->post->post_excerpt 字段,使其在 JSON 响应中显示为 order->note

为此,我还必须扩展支付网关,使其process_payment() 方法接受$user_id 作为输入。这是因为它是开箱即用的编码来对当前登录的用户进行操作,在我的情况下,可能在大多数情况下,是 REST 客户端登录的系统用户,而不是进行购买的实际用户。

扩展网关的另一个好处是现在可以返回错误而不是写入wc_add_notice()。因为这是一个 REST 服务,所以什么都看不到 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 )
                );
        
    

【讨论】:

【参考方案2】:

感谢您给我的指导。

我做了一些更改并简化了步骤。

如下:

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;

我希望这对其他人有帮助。这是一项艰苦的工作,需要反复试验。

【讨论】:

如何通过 WooCommerce REST API 使用此插件 WooCommerce PayPal Powered by Braintree Payment Gateway 进行支付 这个版本省略了扩展网关和将用户ID传递到流程支付方式调用的关键步骤对吗?如:function process_payment($order_id, $user_id),接受的答案对我有用。【参考方案3】:

如果您不处理托管支付网关(需要用户重定向到自己的域来处理像 paypal 这样的支付的网关),那么您可以通过 ajax 请求按照 WC 的方式进行操作:

// this is a function as a callback for a restful api - process_payment

// collect payment related info: billing, shipping info, including shipping_method & payment_method

// put all that info inside $_POST global var

// so that the nonce won't fail
$_REQUEST['_wpnonce'] =
        wp_create_nonce( 'woocommerce-process_checkout' );

// make it look like an ajax request
wc_maybe_define_constant('DOING_AJAX', 1);

add_filter('woocommerce_payment_successful_result', function($response) 
     // wp_send_json appropriate response


WC()->checkout()->process_checkout();

WC()->checkout()->process_checkout() 将为您创建一个订单,指定WC()->cart 不为空。

您也可以为托管支付网关尝试此操作,但它会返回一个 redirect,您可以在移动应用程序的 web 视图中打开它并收取付款。

https://gist.github.com/swport/afd9292412752df9e2e086ac38030e8f

【讨论】:

以上是关于WooCommerce REST API v2:如何处理付款?的主要内容,如果未能解决你的问题,请参考以下文章

WooCommerce REST API致命错误连接问题

WooCommerce REST API 无效的 JSON

WooCommerce REST API - 按修改日期过滤订单

woocommerce通过rest api验证用户名和密码

php facetwp woocommerce rest api check

登录时 WooCommerce REST API 身份验证失败