Woocommerce 支付宝插件初探

优质
小牛编辑
121浏览
2023-12-01

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中完成。

实际测试

后台界面如下

woocommerce alipay back end

在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分钱测试了几次,没有啥大问题,只是即时到帐接口没法测试,需要企业账户才能注册。