前言
前一段时间分享了zencart的部署方法- 基于docker安装部署zen-cart外贸电商独立站 , 除了官方比较大的支付通道如paypal等,还有一些知名度没有那么高的第三方通道没有现成的插件可用。需要自己动手对接,本篇文件记录对接过程。
核心函数
superxpay.php
说明:
此文件包含模块安装卸载,通道信息配置,发起支付订单等功能
function process_button() {
$this->confirmation("ok");
global $order, $currencies, $order_totals;
//*/
$customer=$order->customer;
$billing=$order->billing;
//账单人姓
$FirstName=empty($billing['firstname'])?$customer['firstname']:$billing['firstname'];
//账单人名
$LastName=empty($billing['lastname'])?$customer['lastname']:$billing['lastname'];
//账单人email
$Email=$customer['email_address'];
//账单人电话
$Phone=$customer['telephone'];
//账单人邮编
$ZipCode=empty($billing['postcode'])?$customer['postcode']:$billing['postcode'];
//账单地址
$Address=empty($billing['street_address'])?$customer['street_address']:$billing['street_address'];
//账单人城市
$City=empty($billing['city'])?$customer['city']:$billing['city'];
//账单人省或州
$State=empty($billing['state'])?$customer['state']:$billing['state'];
//账单人国家
$Country=empty($billing['country']['title'])?$customer['country']['title']:$billing['country']['title'];
$delivery=$order->delivery;
//收货人姓
$DeliveryFirstName=empty($delivery['firstname'])?$FirstName:$delivery['firstname'];
//收货人名
$DeliveryLastName=empty($delivery['lastname'])?$LastName:$delivery['lastname'];
//收货人email
$DeliveryEmail=empty($delivery['email_address'])?$Email:$delivery['email_address'];
//收货人电话
$DeliveryPhone=empty($delivery['telephone'])?$Phone:$delivery['telephone'];
//收货人邮编
$DeliveryZipCode=empty($delivery['postcode'])?$ZipCode:$delivery['postcode'];
//收货人地址
$DeliveryAddress=empty($delivery['street_address'])?$Address:$delivery['street_address'];
//收货人城市
$DeliveryCity=empty($delivery['city'])?$City:$delivery['city'];
//收货人省或州
$DeliveryState=empty($delivery['state'])?$State:$delivery['state'];
//收货人国家
$DeliveryCountry=empty($delivery['country']['title'])?$customer['country']['title']:$delivery['country']['title'];
//商户号
$MerNo = MODULE_PAYMENT_SUPERXPAY_SELLER;
//订单号(商户网站生成的订单号)
$BillNo = $_SESSION['_superxpay_order_id'];
unset($_SESSION['_superxpay_order_id']);
//通道类型
$ChannelType = MODULE_PAYMENT_SUPERXPAY_CHANNELTYPE;
//支付成功,返回信息显示用户支付金额
//echo "大小:".count($order_totals);
$_SESSION['CustomerAmount']=$order_totals[count($order_totals)-1]['text'];
//商户密匙
$MD5key = MODULE_PAYMENT_SUPERXPAY_MD5KEY;
//$账单金额
$Amount = round(($order->info['total']) * $currencies->get_value($_SESSION['currency'])*100);
//币种
$Currency = $this->getCurrencyCode($_SESSION['currency']);
//是否开启错误日志
$PayLog = MODULE_PAYMENT_SUPERXPAY_PAYMENT_LOG_STATUS;
// 货物信息
$Products = "";
for ($i=0; $i<sizeof($order->products); $i++) {
$Products=$Products."<GoodsName>".$order->products[$i]["name"]."</GoodsName><Qty>".$order->products[$i]['qty']."</Qty><Price>".number_format($order->products[$i]['price']* $currencies->get_value($_SESSION['currency']), 2, '.', '')."</Price><Currency>".$_SESSION['currency']."</Currency>";
}
$GoodListInfo = "<Goods>".$Products."</Goods>";
//语言
$Language = MODULE_PAYMENT_SUPERXPAY_LANGUAGE;
//返回地址
$ReturnURL = MODULE_PAYMENT_SUPERXPAY_RETURN_URL;
//通知地址
$NoticeURL =HTTP_SERVER .DIR_WS_CATALOG.'index.php?main_page=checkout_payresult_notice';
$MerWebsite= HTTP_SERVER;
//商户网站首页地址
$Remark = HTTP_SERVER;
//TransData
$TransData = "";
//组合加密项
$MD5src = $Amount . '&' . $DeliveryEmail . '&' . $ChannelType . '&' . $Currency . '&' . $MerNo . '&' . $NoticeURL . '&' . $BillNo . '&' . $TransData . '&' . $MD5key;
//加密组合项
$MD5info = md5($MD5src);
//订单备注
$OrderDesc = '';
$process_button_string = zen_draw_hidden_field('MerNo', $MerNo) .
zen_draw_hidden_field('BillNo', $BillNo) .
zen_draw_hidden_field('ChannelType', $ChannelType) .
zen_draw_hidden_field('Amount', $Amount) .
zen_draw_hidden_field('Currency', $Currency) .
zen_draw_hidden_field('PayLog', $PayLog).
zen_draw_hidden_field('Language', $Language) .
zen_draw_hidden_field('MD5info', $MD5info) .
zen_draw_hidden_field('ReturnURL', $ReturnURL) .
zen_draw_hidden_field('NoticeURL', $NoticeURL) .
zen_draw_hidden_field('OrderDesc', $OrderDesc) .
zen_draw_hidden_field('TransData', $TransData) .
zen_draw_hidden_field('MerWebsite', $MerWebsite).
zen_draw_hidden_field('Remark', $Remark).
zen_draw_hidden_field('FirstName', $FirstName) .
zen_draw_hidden_field('LastName', $LastName) .
zen_draw_hidden_field('Email', $Email) .
zen_draw_hidden_field('Phone', $Phone) .
zen_draw_hidden_field('ZipCode', $ZipCode) .
zen_draw_hidden_field('Address', $Address) .
zen_draw_hidden_field('City', $City) .
zen_draw_hidden_field('State', $State).
zen_draw_hidden_field('Country', $Country).
zen_draw_hidden_field('DeliveryFirstName', $DeliveryFirstName) .
zen_draw_hidden_field('DeliveryLastName', $DeliveryLastName) .
zen_draw_hidden_field('DeliveryEmail', $DeliveryEmail) .
zen_draw_hidden_field('DeliveryPhone', $DeliveryPhone) .
zen_draw_hidden_field('DeliveryZipCode', $DeliveryZipCode) .
zen_draw_hidden_field('DeliveryAddress', $DeliveryAddress) .
zen_draw_hidden_field('DeliveryCity', $DeliveryCity) .
zen_draw_hidden_field('DeliveryState', $DeliveryState).
zen_draw_hidden_field('DeliveryCountry', $DeliveryCountry).
zen_draw_hidden_field('Products', $GoodListInfo);
return $process_button_string;
}
submitOrder.php
说明:
组织订单参数,向上游通道提交订单申,获取订单链接后,展示给客户,由客户发起支付。
//提交参数
$PostData = array(
"MerchantNo" => $data['MerNo'],
"OutTradeNo" => $data['BillNo'],
"ChannelType" => $data['ChannelType'],
"CurrencyType" => $data['Currency'],
"Amount" => $data['Amount'], // 分
"Body" => $data['DeliveryEmail'],
"NotifyUrl" => $data['NoticeURL'], //异步通知
"ReturnUrl" => $data['ReturnURL'], //同步回调地址
"TransData" => $data['TransData'],
"Sign" => $data['MD5info'],
"Attach" => "",
"Remark" => "",
);
//获取支付链接
$ResData = curlRemote($PostData);
common.php
function curlRemote($data) {
$fieldsString = http_build_query($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, PAY_GATEWAY);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOBODY, false);
curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_HOST']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fieldsString);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
$res_json = json_decode($result);
if (empty($res_json) || !isset($res_json -> Data)) {
return False;
}
return $res_json -> Data;
}
header_php.php
<?php
//error_reporting(E_ALL);
if(isset($zco_notifier)){
$zco_notifier->notify('NOTIFY_HEADER_START_CHECKOUT_PAYRESULT');
}
//重置通知
$messageStack->reset();
require_once(DIR_WS_MODULES.zen_get_module_directory('require_languages.php'));
/*
$extra_file = DIR_WS_MODULES.'payment/superxpay/email_constant.php';
if(file_exists($extra_file)){
require_once($extra_file);
}
*/
$response = file_get_contents("php://input");
//打印日志
error_log(__METHOD__ . PHP_EOL .print_r($response, true));
if(($_SERVER['REQUEST_METHOD'] != 'POST') || empty($response)) exit('FAIL');
//转换
$data = json_decode(str_replace("'",'"',$response), true, 512, JSON_BIGINT_AS_STRING);
//赋值
$BillNo = trim($data['OutTradeNo']);
$Amount = trim($data['Amount']);
$Succeed = trim($data['Status']);
$rorderno = trim($data['OrderNo']);
$MerNo = trim($data['MerchantNo']);
$MD5info = trim($data['Sign']);
$MD5key = MODULE_PAYMENT_SUPERXPAY_MD5KEY;
$md5str = $rorderno . '&' . $MerNo . '&' . $Amount .'&'. $BillNo .'&'. $Succeed .'&'. $MD5key;
$md5Sign = md5($md5str);
//验证
if($MD5info != $md5Sign) {
$card_order_id = MODULE_PAYMENT_SUPERXPAY_ORDER_STATUS_PAY_SUCCESS_ID;
$comments = $comments . $rorderno . ' - ]';
$sqlOrderStatus = array('orders_status'=>$card_order_id,'orders_date_finished'=>'now()');
$sqlOrderHistoryStatus = array('orders_status_id'=>$card_order_id,'date_added'=>'now()', 'comments' => $comments);
//更新订单状态
zen_db_perform(TABLE_ORDERS,$sqlOrderStatus,'update','orders_id='.(int)$BillNo);
zen_db_perform(TABLE_ORDERS_STATUS_HISTORY,$sqlOrderHistoryStatus,'update','orders_id='.(int)$BillNo);
}
//清理购物车
if($MD5info == $md5Sign && ($Succeed == '1')){
$_SESSION['cart']->reset(true);
unset($_SESSION['cartID'],$_SESSION['orders_id'],$_SESSION['order_summary'],$_SESSION['order_number_created'],$_SESSION['sendto'],$_SESSION['billto'],$_SESSION['shipping'],$_SESSION['payment'],$_SESSION['comments']);
}
exit('SUCCESS');
?>
部署过程
# 获取项目代码, 进入zencart 根目录
cd /opt/lnmp/app/zencart
cp -rf /tmp/zencart-superxpay-gateway/* .
FAQ
设置完成后,支付方式选择不生效
生成随机订单号
/*
* 修改文件 includes\classes\order.php
* 添加函数 create_order_number 生成订单号
*/
function create_order_number(){
global $db;
$order_prefix='2'.date('mdH');
$check=$db->Execute("SELECT orders_id FROM ".TABLE_ORDERS." WHERE orders_id like '".$order_prefix."%' ORDER BY orders_id DESC LIMIT 1");
$order_number= $check->fields['orders_id'] ? $check->fields['orders_id']+1 : $order_prefix.'01';
return $order_number;
}
/*
* create函数 内部修改
*/
//新增变量
$order_number=$this->create_order_number();
//新增$sql_data_array 建值
'orders_id' => $order_number,
//修改$insert_id
//$this->orderId = $this->info['order_id'] = $insert_id = $db->insert_ID();
$this->orderId = $this->info['order_id'] = $insert_id = $order_number;
}
记录日志
error_log(__METHOD__ . PHP_EOL .print_r($response, true));
受益匪浅,感谢博主。
终于找到这篇文章了,感谢作者的分享!
kankan