ayHaru 4 年之前
父节点
当前提交
0840e9ba8f

+ 2 - 2
core/framework/function/http.php

@@ -18,8 +18,8 @@ function http_request($url, $params = array(), $method = 'GET', $multi = false,
     $method = strtoupper($method);
     $ci = curl_init();
     curl_setopt($ci, CURLOPT_USERAGENT, 'PHP-SDK OAuth2.0');
-    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 3);
-    curl_setopt($ci, CURLOPT_TIMEOUT, 3);
+//    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 3);
+//    curl_setopt($ci, CURLOPT_TIMEOUT, 3);
     curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
     curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false);

+ 2 - 1
data/config/dev/refill.ini.php

@@ -7,7 +7,8 @@ $suhc_oil = ['name' => 'suhc','store_id' => 8,'card_type' => ['sinopec'],
 			 			  500 => ['goods_id' => 6228,'price' => 484],
 			 			  1000=> ['goods_id' => 6229,'price' => 968],
 			 			  2000=> ['goods_id' => 6230,'price' => 1976]],
-    		 'period' => ['start' => '8:30','end' => '22:30'],'refill_type' => 'api'];
+    		 'period' => ['start' => '8:30','end' => '23:30'],'refill_type' => 'api'];
+//    		 'period' => ['start' => '8:30','end' => '22:30'],'refill_type' => 'api'];
 $oil_providers = ['suhc' => $suhc_oil];
 
 $config['oil_providers'] = $oil_providers;

+ 17 - 0
data/logic/queue.logic.php

@@ -30,6 +30,8 @@ require_once(BASE_HELPER_PATH . '/room_helper.php');
 require_once(BASE_HELPER_PATH . '/mcard/mcard.php');
 require_once(BASE_HELPER_PATH . '/util_helper.php');
 require_once(BASE_HELPER_PATH . '/third_author/signaturer.php');
+require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
+
 
 class queueLogic
 {
@@ -1388,4 +1390,19 @@ class queueLogic
             return callback(true, '充值成功', ['order_sn' => $order['order_sn']]);
         }
     }
+
+    public function NotifyMerchantComplete($params)
+    {
+        $order_id = intval($params['order_id']);
+        if($order_id <= 0) {
+            return callback(false);
+        }
+        [$success,$err] = refill\RefillFactory::instance()->notify_merchant($order_id);
+        if($success) {
+            return callback(true, '通知机构成功', ['order_id' => $order_id]);
+        }
+        else {
+            return callback(false, '通知机构失败.', ['order_id' => $order_id,"err" => $err]);
+        }
+    }
 }

+ 10 - 0
data/model/refill_order.model.php

@@ -9,6 +9,16 @@ defined('InShopNC') or exit('Access Invalid!');
 
 class refill_orderModel extends Model
 {
+	public function getOrderInfo($condition = array(), $fields = '*', $master = false)
+    {
+        $order_info = $this->table('refill_order')->field($fields)->where($condition)->master($master)->find();
+        if (empty($order_info)) {
+            return array();
+        }
+        
+        return $order_info;
+    }
+
     public function add_refill($params)
     {
         return $this->table('refill_order')->insert($params);

+ 3 - 1
helper/fcgi_server.php

@@ -27,7 +27,9 @@ class fcgi_server
         static $exfiles = ['web_wxnotify.php',
             'wxnotify.php','pub_wxnotify.php','alipay_notify_url.php','dispatch_notify.php','kdniao_notify.php',
             'cmbpay_notify.php','cmbpay_sign.php','wxauthor.php','api/wxLogin/index.php','api/wxLogin/callback.php',
-            'signature.php'];
+            'signature.php',
+            'refill_suhc.php'
+        ];
         $path = BASE_ROOT_PATH . '/mobile/';
         $file = str_replace($path,'',$file);
 

+ 133 - 3
helper/refill/RefillFactory.php

@@ -14,8 +14,10 @@ require_once(BASE_HELPER_PATH . '/refill/suhc/RefillPhone.php');
 require_once(BASE_HELPER_PATH . '/refill/suhc/RefillCallBack.php');
 require_once(BASE_HELPER_PATH . '/refill/CalcMerchantPrice.php');
 
+require_once(BASE_HELPER_PATH . '/refill/beixt/RefillPhone.php');
 
 use Log;
+use QueueClient;
 
 class RefillFactory
 {
@@ -85,11 +87,139 @@ class RefillFactory
             return false;
         }
 
-        if($caller->verify($input)) {
-            $caller->notify($input);
+        if($caller->verify($input))
+        {
+            [$order_id,$success] = $caller->notify($input);
+            if($order_id !== false)
+            {
+                $logic_vr_order = Logic("vr_order");
+                if($success) {
+                    $logic_vr_order->changeOrderStateSuccess($order_id);
+                } else {
+                    $logic_vr_order->changeOrderStateCancel($order_id);
+                }
+
+                $mod_refill = Model('refill_order');
+                $mod_refill->edit($order_id,['notify_time' => time(),'notify_state' => 1]);
+                QueueClient::push("NotifyMerchantComplete",['order_id' => $order_id]);
+            }
         }
-
         return true;
     }
 
+    public function notify_merchant($order_id)
+    {
+        if($order_id <= 0) {
+            return [false,"订单ID小于0"];
+        }
+
+        $vr_order = Model('vr_order');
+        $refill_order = Model('refill_order');
+
+        $order_info = $vr_order->getOrderInfo(['order_id' => $order_id]);
+        $refill_info = $refill_order->getOrderInfo(['order_id' => $order_id]);
+
+        if(empty($order_info) || empty($refill_info)) {
+            return [false,"无此订单"];
+        }
+        if ($refill_info['mch_notify_state'] != 0) {
+            return [false,"已经通知客户方"];
+        }
+
+        $notify_url = $refill_info['notify_url'];
+        if(empty($notify_url)) {
+            return [false,"回调地址为空"];
+        }
+
+        $order_state = $order_info['order_state'];
+        if($order_state == ORDER_STATE_CANCEL) {
+            $state = "CANCEL";
+        }
+        elseif($order_state == ORDER_STATE_SUCCESS) {
+            $state = "SUCCESS";
+        }
+        else {
+            return [false,"错误的订单状态,不能通知."];
+        }
+
+        $mchid = $refill_info['mchid'];
+        $mch_info = Model('merchant')->getMerchant($mchid);
+
+        [$params,$sign] = $this->body($state,$refill_info,$mch_info);
+        $params['sign'] = $sign;
+
+        $resp = http_request($notify_url,$params,'POST');
+
+        if($resp == "SUCCESS") {
+            $refill_order->edit(['order_id' => $order_id],['mch_notify_state' => 1,'mch_notify_times' => ['exp','mch_notify_times+1']]);
+            return [true,""];
+        }
+        else {
+            $refill_order->edit(['order_id' => $order_id],['mch_notify_times' => ['exp','mch_notify_times+1']]);
+            $times = $refill_info['mch_notify_times'] + 1;
+
+            if($times > 80) {
+                $refill_order->edit(['order_id' => $order_id],['mch_notify_state' => 2]);
+            }
+            else {
+                $N = intval($times / 5);
+                $period = intval(pow(2,$N));
+                QueueClient::async_push("NotifyMerchantComplete",['order_id' => $order_id],$period);
+            }
+            return [false,"通知{$times}次,失败."];
+        }
+    }
+
+    private function body($state,$refill_info,$mch_info)
+    {
+        $params = [
+            "mchid"     => $refill_info['mchid'],
+            "order_sn"  => $refill_info['mch_order'],
+            "amount"    => $refill_info['refill_amount'],
+            "cardno"   => $refill_info['card_no'],
+            "trade_no"  => $refill_info['order_sn'],
+            "idcard"    => $refill_info['idcard'] ?? "",
+            "card_name" => $refill_info['card_name'] ?? "",
+            "state"     => $state ];
+
+        $secure_key = $mch_info['secure_key'];
+        $sign = $this->sign($params,$secure_key);
+
+        return[$params,$sign];
+    }
+
+    private function sign($params,$key)
+    {
+        ksort($params);
+
+        $body = "";
+        $i = 0;
+        foreach ($params as $k => $v)
+        {
+            if (false === $this->check_empty($v) && "@" != substr($v, 0, 1))
+            {
+                if ($i == 0) {
+                    $body .= "{$k}" . "=" . urlencode($v);
+                } else {
+                    $body .= "&" . "{$k}" . "=" . urlencode($v);
+                }
+                $i++;
+            }
+        }
+        $body .= "&key={$key}";
+
+        return md5($body);
+    }
+
+    private function check_empty($value)
+    {
+        if (!isset($value))
+            return true;
+        if ($value === null)
+            return true;
+        if (trim($value) === "")
+            return true;
+
+        return false;
+    }
 }

+ 1 - 6
helper/refill/beixt/RefillCallBack.php

@@ -14,13 +14,8 @@ class RefillCallBack implements refill\IRefillCallBack
         return true;
     }
 
-    public function onOil($params)
+    public function notify($params)
     {
 
     }
-
-    public function onPhone($params)
-    {
-        // TODO: Implement onPhone() method.
-    }
 }

+ 27 - 15
helper/refill/suhc/RefillCallBack.php

@@ -5,16 +5,15 @@ namespace refill\suhc;
 
 use refill;
 
-
 class RefillCallBack implements refill\IRefillCallBack
 {
-
     public function verify($params) : bool
     {
         $input = $params;
         unset($input['sign']);
 
-        if($params['sign'] == $this->sign($input)) {
+        $sign = $this->sign($input);
+        if($params['sign'] == $sign) {
             return true;
         }
         else {
@@ -25,32 +24,45 @@ class RefillCallBack implements refill\IRefillCallBack
     private function sign($params)
     {
         ksort($params);
+
         $body = "";
-        foreach ($params as $key => $val){
-            $body .= "{$key}={$val}&";
+        $i = 0;
+        foreach ($params as $k => $v)
+        {
+            if ($i == 0) {
+                $body .= "{$k}";
+                if(!empty($v)) {
+                    $body .= "=" . $v;
+                }
+            }
+            else {
+                $body .= "&" . "{$k}";
+                if(!empty($v)) {
+                    $body .= "=" . $v;
+                }
+            }
+            $i++;
         }
 
-        $body .= "key=".config::KEY;
-
+        $body .= "&key=".config::KEY;
         return md5($body);
     }
 
     public function notify($params)
     {
         $status = intval($params['status']);
-        $ch_trade_no = $params['batchid'];
         $order_sn = $params['onlystr'];
 
-        $logic_vr_order = Logic("vr_order");
-        $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
+        $order_info = Model('vr_order')->getOrderInfo(['order_sn' => $order_sn]);
+        if(empty($order_info)) {
+            return [false,false];
+        }
 
+        $order_id = $order_info['order_id'];
         if($status === 2) {
-
-
-            $logic_vr_order = Logic("vr_order");
-            $logic_vr_order->changeOrderStateSend($order_id);
+            return [$order_id,true];
         } else {
-
+            return [$order_id,false];
         }
     }
 }

+ 1 - 1
helper/refill/suhc/config.php

@@ -9,7 +9,7 @@ class config
     const ORDER_URL = 'http://jiayouka.5800cc.com/kaOrder/createKaOrder.html';
     const KEY = '7yDCLS6S2KzSAJQOUc3vsa';
     const ORGID = 1590993600;
-    const NOTIFY_URL = BASE_SITE_URL . "/mobile/suhc_notify.php";
+    const NOTIFY_URL = BASE_SITE_URL . "/mobile/refill_suhc.php";
     const STOREIDS = ['10280838',
         '611127',
         '10109062',

+ 6 - 6
mobile/control/control.php

@@ -71,7 +71,7 @@ class mobileControl
         $input['sign'] = null;
         $input['from'] = null;
 
-        $data = $this->getSignCotent($input);
+        $data = $this->sign($input);
         $res = openssl_verify($data,base64_decode($sign),$pub);
         Log::record("openssl_verify res={$res}",Log::DEBUG);
 
@@ -88,25 +88,25 @@ class mobileControl
         return false;
     }
 
-    private function getSignCotent($params)
+    private function sign($params)
     {
         ksort($params);
 
-        $stringToBeSigned = "";
+        $body = "";
         $i = 0;
         foreach ($params as $k => $v)
         {
             if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1))
             {
                 if ($i == 0) {
-                    $stringToBeSigned .= "{$k}" . "=" . urlencode($v);
+                    $body .= "{$k}" . "=" . urlencode($v);
                 } else {
-                    $stringToBeSigned .= "&" . "{$k}" . "=" . urlencode($v);
+                    $body .= "&" . "{$k}" . "=" . urlencode($v);
                 }
                 $i++;
             }
         }
-        return $stringToBeSigned;
+        return $body;
     }
 
 

+ 7 - 0
mobile/control/merchant_admin.php

@@ -0,0 +1,7 @@
+<?php
+
+
+class merchant_admin
+{
+
+}

+ 53 - 14
mobile/control/refill.php

@@ -14,16 +14,57 @@ class refillControl extends merchantControl
         parent::__construct();
     }
 
+    private function check_params($params)
+    {
+        if(empty($params['cardno'])) {
+            return [false,'参数没有包含cardno'];
+        }
+        if(empty($params['amount'])) {
+            return [false,'参数没有包含充值金额:amount'];
+        }
+
+        $card_no = $_GET['cardno'];
+        $oil_type = mtopcard\oil_type($card_no);
+
+        if($oil_type == mtopcard\UnknownCard) {
+            return [false,"充值卡不是中石油也不是中石化"];
+        }
+        
+        if($oil_type === mtopcard\PetroChinaCard)
+        {
+            if(empty($params['idcard'])) {
+                return [false,'中石油需要参数没有包含身份证号码:idcard'];
+            }
+            if(empty($params['card_name'])) {
+                return [false,'参数没有包含身份证姓名:card_name'];
+            }
+        }
+
+        if(empty($params['notifyurl'])) {
+            return [false,'参数没有包含notifyurl'];
+        }
+        if(empty($params['order_sn'])) {
+            return [false,'参数没有包含贵方唯一订单号:order_sn'];
+        }
+        return [true,""];
+    }
+
     public function addoilOp()
     {
+        [$success,$error] = $this->check_params($_GET);
+        if($success === false) {
+            return self::outerr(201,$error);
+        }
+
         $amount = intval($_GET['amount']);
         $card_no = $_GET['cardno'];
         $oil_type = mtopcard\oil_type($card_no);
-        $notify_url = $_GET['notify_url'];
+        $notify_url = $_GET['notifyurl'];
+        $mch_order = $_GET['order_sn']; //对方的order
 
         $providers = refill\RefillFactory::instance()->find_oil($amount,$oil_type);
         if(empty($providers)) {
-            return self::outerr(201,"找不到合适的充值通道");
+            return self::outerr(202,"找不到合适的充值通道");
         }
 
         $buyer_id = $this->adminid();
@@ -32,7 +73,7 @@ class refillControl extends merchantControl
         $calc = new refill\CalcMerchantPrice($this->mchid(),$amount);
         $mch_amount = $calc->calc_vgoods_price([]);
         if($mch_amount > $minfo->available_predeposit()) {
-            return self::outerr(202,"余额不足");
+            return self::outerr(203,"余额不足");
         }
 
         $refill_state = false;
@@ -61,23 +102,18 @@ class refillControl extends merchantControl
                 $order_id = $result['data']['order_id'];
                 //虚拟订单表信息扩展
                 $orderext = ['order_id' => $order_id,'order_sn' => $order_sn,'mchid' => $this->mchid(),
+                    'refill_amount' => $amount,'mch_order' => $mch_order,
                     'notify_url' => $notify_url,'channel_name' => $channel_name,
                     'mch_amount' => $mch_amount,'channel_amount' => $price,'order_time' => time(),
                     'card_type' => $oil_type,'card_no' => $card_no];
-                $ret = $mod_refill->add_refill($orderext);
-
-                if($ret) {
-
-                }
-                else {
-                    Log::record("Create Refill Order Error",Log::ERR);
-                }
+                $mod_refill->add_refill($orderext);
             }
             else {
                 continue;
             }
 
-            [$state,$err] = $provider->add($card_no,$oil_type,$amount,$input);
+            $params = ['order_sn' => $order_sn];
+            [$state,$err] = $provider->add($card_no,$oil_type,$amount,$params);
             if($state) {
                 $trade_no = $err;
                 $logic_vr_order = Logic("vr_order");
@@ -85,17 +121,20 @@ class refillControl extends merchantControl
                 $data = ['commit_time' => time(),'ch_trade_no' => $trade_no];
                 $mod_refill->edit($order_id,$data);
                 $refill_state = true;
+                break;
             }
             else {
+                Log::record("channel:{$channel_name} err:{$err}");
                 $logic_vr_order = Logic("vr_order");
                 $order_info = Model('vr_order')->getOrderInfo(['order_id' => $order_id]);
                 $logic_vr_order->changeOrderStateCancel($order_info,'',"调用{$channel_name}接口失败");
             }
         }
+
         if($refill_state) {
-            return self::outsuccess(['state' => true]);
+            return self::outsuccess(['state' => true,'trade_no' => $order_sn]);
         } else {
-            return self::outerr(203,"充值失败.");
+            return self::outerr(204,"充值失败.");
         }
     }
 

+ 0 - 1
mobile/signature.php

@@ -2,7 +2,6 @@
 
 Log::record("This is signatrue file.");
 
-
 $signature = $_GET["signature"];
 $timestamp = $_GET["timestamp"];
 $nonce = $_GET["nonce"];

+ 16 - 36
test/TestRefill.php

@@ -14,7 +14,6 @@ require_once(BASE_CORE_PATH . '/framework/function/http.php');
 require_once(BASE_HELPER_PATH . '/refill/RefillFactory.php');
 require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
 
-require_once(BASE_HELPER_PATH . '/refill/beixt/RefillPhone.php');
 class TestRefill extends TestCase
 {
     public static function setUpBeforeClass(): void
@@ -49,61 +48,36 @@ class TestRefill extends TestCase
     public function testAddoil()
     {
         $params = ['mchid' => 1,'cardno' => '1000111100021211884','amount' => "100","act"=>"refill","op"=>"addoil",
-            'notify_url'=> BASE_SITE_URL . "/mobile/index.php",'client_type' => 'ios'];
+            'order_sn' => "13281474",
+            'notifyurl'=> BASE_SITE_URL . "/mobile/suhc_notify.php"];
         $this->send($params);
     }
 
     public function testSuhcCB()
     {
-        $params = ['onlystr' => '200649600557717656',
+        $notifyurl = BASE_SITE_URL . "/mobile/refill_suhc.php";
+
+        $params = ['onlystr' => '200660783085683671',
             'amt' => 100,
             'jdno'=>'',
-            'notifyurl' => "https%3A%2F%2Fwww.xyzshops.cn%2Fmobile%2Fsignature.php",//https://www.xyzshps.cn/mobile/signature.php",
+            'notifyurl' => $notifyurl,
             'cardtype' => 'Sinoepc',
-            'batchid' => 15737,
+            'batchid' => 15678,
             'cardno' => '1000111100021211884',
             'orgid' => '1590993600',
             'status' => 2];
 
-        //onlystr=200649600557717656&sign=20e79508c9765a4bf568beb162dbfba3&amt=100&notifyurl=https%3A%2F%2Fwww.xyzshops.cn%2Fmobile%2Fsignature.php&
-        //jdno&cardtype=Sinoepc&batchid=15737&cardno=1000111100021211884&orgid=1590993600&status=2
-
-        //sign=20e79508c9765a4bf568beb162dbfba3
-
         $sign = $this->md5_sign($params);
+        $params['sign'] = $sign;
 
-
-        $x = "amt=100.00&batchid=17007&cardno=1000111100021211884&cardtype=Sinoepc&jdno=133668223223&notifyurl=https://www.xyzshops.cn/mobile/signature.php&onlystr=200649600557717656
-        &orgid=1590993600&status=2&key=7yDCLS6S2KzSAJQOUc3vsa";
-        $x = md5($x);
-    }
-    public function testSuhcCBA()
-    {
-        $params = ['onlystr' => '200649600557717656',
-            'amt' => "100.00",
-            'jdno'=>'133668223223',
-            'notifyurl' => "https://www.xyzshops.cn/mobile/signature.php",//https://www.xyzshps.cn/mobile/signature.php",
-            'cardtype' => 'Sinoepc',
-            'batchid' => 17007,
-            'cardno' => '1000111100021211884',
-            'orgid' => '1590993600',
-            'status' => 2];
-
-        //onlystr=200649600557717656&sign=20e79508c9765a4bf568beb162dbfba3&amt=100&notifyurl=https%3A%2F%2Fwww.xyzshops.cn%2Fmobile%2Fsignature.php&
-        //jdno&cardtype=Sinoepc&batchid=15737&cardno=1000111100021211884&orgid=1590993600&status=2
-
-        //sign=20e79508c9765a4bf568beb162dbfba3
-
-        $sign = $this->md5_sign($params);
+        $resp = http_request($notifyurl,$params,'POST');
+        Log::record($resp,Log::DEBUG);
     }
 
     private function md5_sign($params)
     {
         ksort($params);
         $body = "";
-//        foreach ($params as $key => $val){
-//            $body .= "{$key}={$val}&";
-//        }
 
         $i = 0;
         foreach ($params as $k => $v)
@@ -127,6 +101,12 @@ class TestRefill extends TestCase
         return md5($body);
     }
 
+    public function testCallMech()
+    {
+        $logic = Logic('queue');
+        $logic->NotifyMerchantComplete(['order_id' => 289]);
+    }
+
     private function send($params)
     {
         $mchid = $params['mchid'];