• 微擎开发之人人商城添加第三方支付系列


    背景介绍

    商城采用的是基于微擎开发的人人商城,做的是跨境电商,需要接入通联支付打通跟环球云仓和海关那边报关的需要,首先要接入通联支付进入系统中。申请好需要的基础信息包括商户号、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 appxxxxxxlibrary;
    
    use thinkDb;
    
    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(" ", " ", "	", "
    ", "
    ");
            $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(" ", " ", "	", "
    ", "
    ");
            $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;
        }
    }
    
  • 相关阅读:
    SQL中的选择判断
    Rsync
    LAMP性能优化的一些建议
    Toad9.7与Oracle11g在X86的Win7下的情况
    IIS中IUSR_和IWAM_:计算机名帐户的用户名和密码的用途
    winform编程中的跨线程访问资源(转)
    MSTDC服务的应用及相关错误的解决方案(转载)
    SQL Server 错误代码详解
    poj 1777梅森素数
    hdu 2815 baby_step c可为非素数
  • 原文地址:https://www.cnblogs.com/weblm/p/11013268.html
Copyright © 2020-2023  润新知