Woocommerce 支付宝插件初探
Woocommerce虽然没有中文语言包,把前台做成中文后台保留英文确是一件很简单的事,如果你略懂中文,想用Woocommerce做个小网店,是个不错的选择。最麻烦的是支付方式,国外的产品基本不支持支付宝、财付通等国内流行的支付方式,所以研究了下如何让Woocommerce支持支付宝。
支付宝文档
在网上搜了下,只能搜到一个Woocommerce支付宝产品,虽然我没有购买,但大体猜测这个支付宝功能不是以插件形式写的,支付宝网关添加到Woocommerce的核心文件中,要更新的话只能从作者这里更新,有点麻烦。
给Woocommerce添加网关不难,文档很丰富,在文章Woocommerce如何扩展支付方式中介绍过。难的是支付宝,示例代码看着很痛苦,我对电商本来就了解的不多,许多术语都不懂,支付宝的文档对我来说就是一本看一分钟就会睡着的天书。
支付宝工作流程
支付宝常用有三种网关接口:即时到帐接口、双功能接口和担保买卖接口。
虽然示例代码中这三种接口分别带有自己的库文件,其实库文件是相同的,只需要一份。使用wp-alipay插件时,发现他用了三个库,分别放在目录lib-direct、lib-dualfun和lib-escow中,其实这是没必要的。支付宝区分这三种接口只是靠一个参数service,如下
"service" => "create_partner_trade_by_buyer" //担保买卖接口 "service" => "trade_create_by_buyer" //双功能接口 "service" => "create_direct_pay_by_user" //即时到帐接口
支付宝三种方式的区别是提交的数据不同,我选择用get方式向支付宝发送数据,在Woocommerce中写了一个函数用来获取支付宝需要传递的数据。
构造支付宝所需要的参数数组
function get_alipay_args( $order ) { global $woocommerce; $paymethod = 'directPay'; $order_id = $order->id; if ($this->debug=='yes') $this->log->add( 'alipay', 'Generating payment form for order #' . $order_id . '. Notify URL: ' . $this->notify_url); $buyer_name = $order->billing_last_name.$order->billing_first_name; if( $this->payment_method == 'direct') $service = 'create_direct_pay_by_user'; else if ( $this->payment_method == 'dualfun' ) $service = 'trade_create_by_buyer'; else if ( $this->payment_method == 'escrow' ) $service = 'create_partner_trade_by_buyer'; $total_fee = $order->order_total; $alipay_args = array( "service" => $service, "payment_type" => "1", "partner" => trim($this->partnerID), "_input_charset" => 'utf-8', "seller_email" => trim($this->alipay_account), "return_url" => $this->get_return_url( $order ), "notify_url" => $this->notify_url, "out_trade_no" => $order->order_key.'|'.$order->id, "subject" => $buyer_name, "body" => $order->customer_note, "price" => $total_fee, "quantity" => 1 ); if( $this->payment_method != 'direct' ) { $add_args = array( "logistics_fee" => '0', "logistics_type" => 'EXPRESS', //optional EXPRESS(快递)、POST(平邮)、EMS(EMS) "logistics_payment" => 'SELLER_PAY', //optional SELLER_PAY(卖家承担运费)、BUYER_PAY(买家承担运费) "receive_name" => $buyer_name, "receive_address" => $order->billing_address_1, "receive_zip" => $order->shipping_postcode, //"receive_phone" => $order->billing_phone, "receive_mobile" => $order->billing_phone ); $alipay_args = array_merge($alipay_args, $add_args); } $alipay_args = apply_filters( 'woocommerce_alipay_args', $alipay_args ); return $alipay_args; }
获取支付宝config参数
/** * Get Alipay config info for processing payment **/ function get_alipay_config( $order ){ $alipay_config = array(); $alipay_config['partner'] = trim($this->partnerID); $alipay_config['key'] = trim($this->secure_key); $alipay_config['seller_email'] = trim($this->alipay_account); $alipay_config['return_url'] = $this->get_return_url( $order ); $alipay_config['notify_url'] = $this->notify_url; $alipay_config['sign_type'] = 'MD5'; $alipay_config['input_charset']= 'utf-8'; $alipay_config['transport'] = 'http'; $alipay_config = apply_filters( 'woocommerce_alipay_config_args', $alipay_config ); return $alipay_config; }
建立支付宝query string
/** * Build Alipay http string to pass to Alipay gateway **/ function build_alipay_string( $order ) { require_once( "lib/alipay_service.class.php"); //Get alipay args $alipay_args = $this->get_alipay_args( $order ); $alipay_config = $this->get_alipay_config( $order ); $alipayService = new AlipayService( $alipay_config ); $alipay_submit = new AlipaySubmit(); $para = $alipay_submit->buildRequestPara($alipay_args,$alipay_config); $query_string = http_build_query( $para, '', '&' ); $alipay_string = $alipayService->alipay_gateway_new.$query_string; return $alipay_string; }
有了这些,process_payment()函数只需要几行代码,就可以把数据发送给支付宝了。我们传递的参数中定义了return_url和notify_url,出于安全性考虑,return_url只用来获取创建的支付宝交易号,不做其他处理。写数据库更新订单的操作在notify_url中完成。
实际测试
后台界面如下
在Alipay Payment Gateway Type处可以选择使用哪种支付方式,支持即时到帐、双功能和担保买卖。
前台界面如下
用户在checkout页面选择Alipay支付,点击Place order就会直接到达支付宝页面,支付完成后会跳回网站,显示订单已接受,并显示接收到的支付宝交易号,订单状态会被自动更新为Processing。
支付宝异步通知
支付宝会用异步方式向服务器(notify_url)发送支付结果,每次发送都会包含状态,状态根据你选择支付方式不同而有所差异,可以根据状态更新订单状态,或者为订单添加备注,比如担保买卖中有四种状态
WAIT_BUYER_PAY——等待买家付款
WAIT_SELLER_SEND_GOODS——买家已付款,等待卖家发货
WAIT_BUYER_CONFIRM_GOODS——等待买家确认收货
TRADE_FINISHED——交易完成
必须echo ‘success’给支付宝,否则支付宝会每隔一段时间就向服务器发送一次信息,直到24小时候以后超时才停止。
用1分钱测试了几次,没有啥大问题,只是即时到帐接口没法测试,需要企业账户才能注册。