weblm

背景介绍

商城采用的是基于微擎开发的人人商城,做的是跨境电商,需要接入通联支付打通跟环球云仓和海关那边报关的需要,首先要接入通联支付进入系统中。申请好需要的基础信息包括商户号、appid等。文档地址:https://aipboss.allinpay.com/know/devhelp/index.php

接入通联支付之H5收银宝支付

在core/model目录下新建一个文件,比如说叫tlpay.php,直接上代码

<?php

if (!defined(\'IN_IA\')) {
    exit(\'Access Denied\');
}
class Tlpay_EweiShopV2Model{
    /**
     * 支付商户号
     * @var string
     */
    public static $CUSID;
    /**
     * 支付appid
     * @var string
     */
    public static $APPID;
    /**
     * md5加密key
     * @var string
     */
    public static $KEY;
    /**
     *字符集
     * @var string
     */
    public static $CHARSET =\'\';
    /**
     * 版本
     * @var string
     */
    public static $VERSION;
    /**
     * 支付请求地址
     * @var string
     */
    public static $URL;

    /**
     * 获取签名
     * @param $array
     * @param $appkey
     * @return string
     */
    public function SignArray($array,$appkey){
        $array[\'key\'] = $appkey;// 将key放到数组中一起进行排序和组装
        ksort($array);
        $blankStr = $this->ToUrlParams($array);
        $sign = strtoupper(md5($blankStr));
        return $sign;
    }

    /**
     * @param $array
     * @return string
     */
    public function ToUrlParams($array)
    {
        $buff = "";
        foreach ($array as $k => $v)
        {
            if($v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * @param array $array
     * @param $appkey
     * @return bool
     */
    public function ValidSign(array $array,$appkey){
        $sign = $array[\'sign\'];
        unset($array[\'sign\']);
        $array[\'key\'] = $appkey;
        $mySign = $this->SignArray($array, $appkey);
        return strtolower($sign) == strtolower($mySign);
    }

    /**
     * 组织数据
     * @param $order_id
     * @return array|bool
     */
    public function postData($order_id)
    {
        if($order_id==\'\'){
            return false;
        }
        $redirect_url = mobileUrl(\'order/pay/success\',array(\'id\'=>$orderid,\'result\'=>"true")); //支付成功后跳转地址
        $redirect_url =\'http://\'.$_SERVER[\'HTTP_HOST\'].\'/app/\'.substr($redirect_url,2);
        $orderInfo  = pdo_get(\'ewei_shop_order\',[\'id\'=>$order_id],[\'ordersn\',\'price\']);
        $params = array();
        $params["cusid"] = static::$CUSID;
        $params["appid"] = static::$APPID;
        $params["version"] = static::$VERSION;
        $params["orgid"] = \'\';
        $params["randomstr"] =$this->createNoncestr();
        $params["trxamt"] = $orderInfo[\'price\']*100;//订单金额
        $params["reqsn"] = $orderInfo[\'ordersn\'];//订单号
        $params["charset"] = static::$CHARSET;//mobileUrl("order/pay/success", array( "id" => $order["id"], "type" => "credit", "ordersn" => $order["ordersn"] ))
        //$params["returl"] = \'http://\'.$_SERVER[\'HTTP_HOST\'].\'/app/\'.substr(mobileUrl(\'order/pay/complete\',array(\'id\'=>$orderid,"type" => "tlpay")),2);//self::$data[\'returl\'];
        $params["returl"] = $redirect_url;//mobileUrl("order/pay/success", array( "id" => $order_id, \'result\'=>"true","type" => "tlpay"));
        $params["notify_url"] =\'http://\'.$_SERVER[\'HTTP_HOST\']."/addons/ewei_shopv2/payment/tlpay/notify.php";
        $params["body"] = \'xxxx\';
        $params["remark"] = \'xxxx\';
        $params["validtime"] = \'10\';
        $params["limit_pay"] =\'no_credit\';
        $params["asinfo"] =\'\';
        $sign = $this->SignArray($params,static::$KEY);
        $params[\'sign\'] = $sign;
        return $params;

    }

    /**
     * 模拟微信浏览器 参考网上的代码
     * @param $url
     * @param $data
     * @param $referer
     * @param $cookie
     * @return mixed
     */
    public function makeHttp($url, $data, $referer, $cookie)
    {
        $header = array();
        $header[] = \'Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*\';
        $header[] = \'Connection: Keep-Alive\';
        $header[] = \'Accept-Language: zh-cn\';
        $header[] = \'Cache-Control: no-cache\';
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        //curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_USERAGENT, \'Mozilla/5.0 (Linux; U; Android 2.3.6; zh-cn; GT-S5660 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MicroMessenger/4.5.255\');
        curl_setopt($ch, CURLOPT_REFERER, $referer);
        curl_setopt($ch, CURLOPT_COOKIE, $cookie);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $result = curl_exec($ch);
        curl_close($ch);
        return $result;

    }

    /**
     *  作用:产生随机字符串,不长于32位
     */
    public function createNoncestr( $length = 32 ){
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str ="";
        for ( $i = 0; $i < $length; $i++ )  {
            $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
        }
        return $str;
    }





}

在pay.php的success方法中加入针对通联支付的处理

接入通联支付之商户支付验证报关接口

代码如下:

<?php

namespace app\xxxxxx\library;

use think\Db;

class Tlpay
{
    private static $data = array(
        \'VERSION\' => \'v5.6\',//版本
        \'VISITOR_ID\' => \'MCT\',//接入方ID
        \'MCHT_ID\' => \'xxxx\',//报关用的商户号
        \'CHARSET\' => \'1\',//字符集
        \'SIGN_TYPE\' => \'1\',//签名方式
        \'CUSTOMS_CODE\' => \'xxxxxx\',//海关类别
        \'PAYMENT_CHANNEL\' => \'2\',//支付渠道
        \'CUS_ID\' => \'xxxxxxxx\',//支付用的商户号
        \'CURRENCY\' => \'156\',//支付币制
        \'ESHOP_ENT_CODE\' => \'xxxxxxx\',//电商平台代码
        \'ESHOP_ENT_NAME\' => \'xxxxxxxx\',//电商平台名称
        \'PAPER_TYPE\' => \'01\',//支付人证件类型
        \'PRO_URL\' => \'https://service.allinpay.com/customs/pvcapply\',//生产环境
        \'DEV_URL\' => \'\',//测试环境
    );

    /**
     * 格式化数据
     * @param $data
     * @param DOMDocument|null $dom
     * @param DOMElement|null $xml
     * @param string $ele
     * @return mixed
     */
    public static function convert($data, \DOMDocument $dom = null, \DOMElement $xml = null, $ele = \'PAYMENT_INFO\')
    {
        if (!$dom) {
            $dom = new \DOMDocument(\'1.0\', \'UTF-8\');
            $dom->formatOutput = true;
        }
        if (!$xml) {
            $xml = $dom->createElement($ele);
            $dom->appendChild($xml);
        }
        foreach ($data As $key => $val) {
            $key = !is_string($key) ? $xml->tagName : $key;
            if (is_array($val) && count($val) && preg_match(\'/^[\d]+$/\', implode(\'\', array_keys($val)))) {
                foreach ($val As $k => $v) {
                    $e = $dom->createElement($key);
                    $xml->appendChild($e);

                    if (is_object($v) || is_array($v)) {
                        self::convert($v, $dom, $e);
                        continue;
                    }
                    if (is_string($v) && preg_match(\'/<[^>]+>/\', $v)) {
                        $e->appendChild($dom->createCDATASection($v));
                    } else {
                        $e->nodeValue = htmlspecialchars((string)$v);
                    }
                }
                continue;
            }
            if ((is_object($val) || is_array($val)) && count($val)) {
                $e = $dom->createElement($key);
                $xml->appendChild($e);
                self::convert($val, $dom, $e);
                continue;
            }
            if ((is_object($val) || is_array($val)) && !count($val)) {
                $xml->appendChild($dom->createElement($key));
                continue;
            }
            $e = $dom->createElement($key);
            $xml->appendChild($e);
            if (is_string($val) && preg_match(\'/<[^>]+>/\', $val)) {
                $e->appendChild($dom->createCDATASection($val));
            } else {
                $e->nodeValue = htmlspecialchars((string)$val);
            }
        }
        return $dom->saveXML();
    }

    /**
     * 获取签名
     * @param $str
     * @return string
     */
    public function get_sign($str)
    {
        $sdata = substr($str, 39);
        $par = array(" ", " ", "\t", "\n", "\r");
        $re = str_replace($par, \'\', $sdata);
        $md5key = \'xxxxxxxxxxx\';
        $mstr = $re . \'<key>\' . $md5key . \'</key>\';
        $md5re = strtoupper(md5($mstr));
        return $md5re;
    }

    /**
     * 截取标准xml数据组合紧密数据
     * @param $str
     * @return mixed
     */
    public function cut_str($str)
    {
        $sdata = substr($str, 39);
        $par = array(" ", " ", "\t", "\n", "\r");
        $re = str_replace($par, \'\', $sdata);
        return $re;
    }

    /**
     * cURL http请求
     * @param $url
     * @param $params
     * @param string $method
     * @return mixed
     */
    private function http($url, $params = array(), $method = "POST", $headers = array())
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_POST, TRUE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        if ($headers != "") {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        } else {
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(\'Content-type: application/x-www-form-urlencoded\'));
        }

        $output = curl_exec($ch);
        curl_close($ch);
        return $output;//base64格式的
    }

    /**
     * xml转数组
     * @param $xml
     * @return mixed
     */
    public function xml_array($xml)
    {
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, \'SimpleXMLElement\', LIBXML_NOCDATA)), true);
        return $values;

    }

    /**
     * 获取响应信息解码 base64转码 然后转数组
     * @param $str
     * @return mixed
     */
    public function decode_res($str)
    {
        $res = base64_decode($str);
        $header_str = \'<?xml version="1.0" encoding="UTF-8"?>\';
        $new_str = $header_str . $res;
        $result = $this->xml_array($new_str);
        return $result;

    }

    /**
     * 根据订单获取信息
     * @param $ordersn
     */
    public function get_orderinfo($ordersn)
    {
        $info = Db::table(\'ims_ewei_shop_order\')
            ->alias(\'a\')
            ->join(\'ims_ewei_shop_member_address b\', \'a.addressid = b.id \', \'LEFT\')
            ->field(\'a.price,a.paytime,a.transid,b.realname,b.mobile,b.purchaser_id\')
            ->where(\'a.paytype\', \'=\', xx)
            ->where(\'b.realname IS NOT NULL\')
            ->where(\'b.mobile IS NOT NULL\')
            ->where(\'b.purchaser_id IS NOT NULL\')
            ->where(\'a.ordersn\', \'=\', $ordersn)
            ->find();
        return $info;
    }

    /**
     * @param $ordersn
     * @return array
     */
    public function get_body($ordersn)
    {
        $info = $this->get_orderinfo($ordersn);

        $bodyData = array(
            \'CUSTOMS_CODE\' => self::$data[\'CUSTOMS_CODE\'],
            \'PAYMENT_CHANNEL\' => self::$data[\'PAYMENT_CHANNEL\'],//支付渠道
            \'CUS_ID\' => self::$data[\'CUS_ID\'],//支付用的商户号
            \'PAYMENT_DATETIME\' => date("YmdHis", $info[\'paytime\']),
            \'MCHT_ORDER_NO\' => $ordersn,
            \'PAYMENT_ORDER_NO\' => $info[\'transid\'],
            \'PAYMENT_AMOUNT\' => $info[\'price\'] * 100,//支付总额 分
            \'CURRENCY\' => self::$data[\'CURRENCY\'],//支付币制
            \'ESHOP_ENT_CODE\' => self::$data[\'ESHOP_ENT_CODE\'],//电商平台代码
            \'ESHOP_ENT_NAME\' => self::$data[\'ESHOP_ENT_NAME\'],//电商平台名称
            \'PAYER_NAME\' => $info[\'realname\'],//支付人姓名
            \'PAPER_TYPE\' => self::$data[\'PAPER_TYPE\'],//支付人证件类型
            \'PAPER_NUMBER\' => $info[\'purchaser_id\'],//支付人证件号码
            \'PAPER_PHONE\' => $info[\'mobile\'],//支付人手机号
            \'PAPER_EMAIL\' => \'\',//支付人邮箱

        );
        $xmlData = self::convert($bodyData, null, null, $ele = \'BODY\');
        return $xmlData;
    }

    /**
     * 组合数据
     * @param $ordersn
     */
    public function format_data($ordersn)
    {
        $bodyXml = $this->get_body($ordersn);
        $info = $this->get_orderinfo($ordersn);
        $params = array();
        $params[\'HEAD\'][\'VERSION\'] = self::$data[\'VERSION\'];
        $params[\'HEAD\'][\'VISITOR_ID\'] = self::$data[\'VISITOR_ID\'];
        $params[\'HEAD\'][\'MCHT_ID\'] = self::$data[\'MCHT_ID\'];
        $params[\'HEAD\'][\'ORDER_NO\'] = $ordersn;
        $params[\'HEAD\'][\'TRANS_DATETIME\'] = date(\'YmdHis\');
        $params[\'HEAD\'][\'CHARSET\'] = self::$data[\'CHARSET\'];
        $params[\'HEAD\'][\'SIGN_TYPE\'] = self::$data[\'SIGN_TYPE\'];
        $params[\'HEAD\'][\'SIGN_MSG\'] = $this->get_sign($bodyXml);
        $params[\'BODY\'][\'CUSTOMS_CODE\'] = self::$data[\'CUSTOMS_CODE\'];
        $params[\'BODY\'][\'PAYMENT_CHANNEL\'] = self::$data[\'PAYMENT_CHANNEL\'];
        $params[\'BODY\'][\'CUS_ID\'] = self::$data[\'CUS_ID\'];
        $params[\'BODY\'][\'PAYMENT_DATETIME\'] = date("YmdHis", $info[\'paytime\']);
        $params[\'BODY\'][\'MCHT_ORDER_NO\'] = $ordersn;
        $params[\'BODY\'][\'PAYMENT_ORDER_NO\'] = $info[\'transid\'];
        $params[\'BODY\'][\'PAYMENT_AMOUNT\'] = $info[\'price\'] * 100;
        $params[\'BODY\'][\'CURRENCY\'] = self::$data[\'CURRENCY\'];
        $params[\'BODY\'][\'ESHOP_ENT_CODE\'] = self::$data[\'ESHOP_ENT_CODE\'];
        $params[\'BODY\'][\'ESHOP_ENT_NAME\'] = self::$data[\'ESHOP_ENT_NAME\'];
        $params[\'BODY\'][\'PAYER_NAME\'] = $info[\'realname\'];
        $params[\'BODY\'][\'PAPER_TYPE\'] = self::$data[\'PAPER_TYPE\'];
        $params[\'BODY\'][\'PAPER_NUMBER\'] = $info[\'purchaser_id\'];
        $params[\'BODY\'][\'PAPER_PHONE\'] = $info[\'mobile\'];
        $params[\'BODY\'][\'PAPER_EMAIL\'] = \'\';
        $xmlInfo = self::convert($params);
        $mainInfo = $this->cut_str($xmlInfo);
        return base64_encode($mainInfo);
    }

    /**获取结果
     * @param $ordersn
     */
    public function get_res($ordersn)
    {
        $post = $this->format_data($ordersn);
        $data = "data=" . urlencode($post);
        $url = self::$data[\'PRO_URL\'];
        $res = $this->http($url, $data);
        $data = $this->decode_res($res);
        //dump($data);
        $log[\'ordersn\'] = $data[\'HEAD\'][\'ORDER_NO\'];
        $log[\'ctime\'] = time();
        $log[\'utime\'] = time();
        if ($data[\'BODY\'][\'RETURN_CODE\'] == \'0000\') {
            $log[\'status\'] = 1;
        } else {
            $log[\'status\'] = 2;
            $log[\'errmsg\'] = $data[\'BODY\'][\'RETURN_MSG\'];
        }
        Db::name(\'xxxxxxxx\')->insert($log);
        Db::name(\'ewei_shop_order\')->where(\'ordersn\', $data[\'HEAD\'][\'ORDER_NO\'])->update([\'tl_sync_status\' => $log[\'status\']]);
        return true;
    }
}

分类:

技术点:

相关文章: