zencart 商城对接第三方支付通道

行云流水
2022-07-29 / 2 评论 / 542 阅读 / 正在检测是否收录...

前言

前一段时间分享了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));

评论 (2)

取消
只有登录/注册用户才可评论
  1. 头像
    流水哥徒弟
    中国福建省 · Windows 10 · FireFox
    沙发

    受益匪浅,感谢博主。

    回复
  2. 头像
    coder00001
    中国广东省 · Windows 10 · Google Chrome
    板凳

    终于找到这篇文章了,感谢作者的分享!

    回复
  3. 头像
    aaa
    美国 · Windows 10 · Google Chrome
    地毯

    kankan

    回复