fly 5 роки тому
батько
коміт
4778aea855

Різницю між файлами не показано, бо вона завелика
+ 464 - 162
app/Http/Controllers/Wap/Pay/OrdersController.php


+ 1 - 0
app/Http/Routes/Wap/WapRoutes.php

@@ -17,6 +17,7 @@ Route::group(['domain'=>env('PAY_WAP_DOMAIN'),'namespace'=>'App\Http\Controllers
     Route::any('pay/wcback_palmpay','Pay\OrdersController@wcback_palmpay');
     Route::any('pay/wcback_originbank','Pay\OrdersController@wcback_originbank');
     Route::any('pay/wcback_smkpay','Pay\OrdersController@wcback_smkpay');
+    Route::any('pay/wcback_union','Pay\OrdersController@wcback_union');
     Route::post('pay/reportError','Pay\OrdersController@reportError');
     //包月
     Route::get('monthpay/getRedirectUrl','Pay\getH5RedirectUrl@getRedirectUrl');

+ 31 - 0
app/Libs/Pay/Merchants/PayMerchantInterface.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Libs\Pay\Merchants;
+
+use Illuminate\Http\Request;
+
+interface PayMerchantInterface
+{
+    /**
+     * 支付下单
+     * @param array $data 
+     */
+    public function send(array $data);
+    /**
+     * 支付回调
+     * @param lluminate\Http\Request $request
+     * @param string $callback 回调函数
+     */
+    public static function notify(Request $request, callable $callback);
+    /**
+     * 订单查询
+     * @param string $trade_no 商户订单号
+     * @return bool 
+     */
+    public function query(string $trade_no);
+    /**
+     * 生成签名
+     * @param array $data 
+     */
+    public function makeSign(array $data);
+}

+ 148 - 0
app/Libs/Pay/Merchants/UnionPay.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace App\Libs\Pay\Merchants;
+
+use App\Modules\Subscribe\Services\OrderService;
+use Exception;
+use GuzzleHttp\Client;
+use Illuminate\Http\Request;
+use DB;
+
+/**
+ * 银联支付
+ */
+class UnionPay implements PayMerchantInterface
+{
+    private $make_order_url = 'https://qr-test2.chinaums.com/netpay-portal/webpay/pay.do';
+    private $query_order_url = 'https://qr-test2.chinaums.com/netpay-route-server/api/';
+    private $msgType = 'WXPay.jsPay';
+    private $signType = 'MD5';
+    private $mid;
+    private $tid;
+    private $instMid;
+    private $msgSrc;
+    private $msgSrcId;
+    private $key;
+
+
+    public function __construct(array $config)
+    {
+        $this->mid = $config['mid'];
+        $this->tid = $config['tid'];
+        $this->instMid = $config['instMid'];
+        $this->msgSrc = $config['msgSrc'];
+        $this->msgSrcId = $config['msgSrcId'];
+        $this->key = $config['key'];
+    }
+
+    private function setConfig(array $config)
+    {
+        $this->mid = $config['mid'];
+        $this->tid = $config['tid'];
+        $this->instMid = $config['instMid'];
+        $this->msgSrc = $config['msgSrc'];
+        $this->msgSrcId = $config['msgSrcId'];
+        $this->key = $config['key'];
+    }
+
+    public function send(array $data)
+    {
+        $result = [
+            'mid' => $this->mid,
+            'tid' => $this->tid,
+            'instMid' => $this->instMid,
+            'msgSrc' => $this->msgSrc,
+            'msgSrcId' => $this->msgSrcId,
+            'msgType' => $this->msgType,
+            'signType' => $this->signType,
+            'requestTimestamp' => date('Y-m-d H:i:s'),
+            'notifyUrl' => env('UNIONPAY_NOFITY_URL'),
+            'returnUrl' => urlencode($data['pay_wait_url']),
+            'totalAmount' => $data['price'],
+            'merOrderId' => $this->msgSrcId . $data['trade_no'],
+        ];
+        $result['sign'] = $this->makeSign($result);
+        $query_params = http_build_query($result);
+        return $this->make_order_url . '?' . $query_params;
+    }
+
+    public function query($trade_no)
+    {
+        $query_params = [
+            'msgType' => 'query',
+            'requestTimestamp' => date('Y-m-d H:i:s'),
+            'mid' => $this->mid,
+            'tid' => $this->tid,
+            'instMid' => $this->instMid,
+            'msgSrc' => $this->msgSrc,
+            'msgSrcId' => $this->msgSrcId,
+            'signType' => $this->signType,
+            'merOrderId' => $trade_no,
+        ];
+        $query_params['sign'] = $this->makeSign($query_params);
+        try {
+            $client = new Client(['base_uri' => $this->query_order_url, 'timeout' => 3]);
+            $result = $client->request('POST', '/mct1/payorder', ['form_params' => $query_params])->getBody()->getContents();
+            if ($result) {
+                $result = json_decode($result);
+                if ($result->errCode === 'SUCCESS' && $result->status === 'TRADE_SUCCESS') {
+                    return true;
+                }
+            }
+        } catch (Exception $e) { }
+
+        return false;
+    }
+
+    public static function notify(Request $request, callable $callback)
+    {
+        $data = $request->all();
+        if ($data['status'] === 'TRADE_SUCCESS') {
+            $trade_no = $data['merOrderId'];
+            if ($trade_no) {
+                $order = OrderService::getByTradeNo($trade_no);
+                $order->transaction_id = $data['targetOrderId'];
+                if ($order) {
+                    $pay_merchant = DB::table('pay_merchants')->select('appid', 'source', 'config_info')
+                        ->where('id', $order->pay_merchant_id)->where('is_enabled', 1)->first();
+                    $instance = new UnionPay(json_decode($pay_merchant->config_info, true));
+                    $sign = $instance->makeSign($data);
+                    if ($sign === $data['sign']) {
+                        if (call_user_func_array($callback, [$order])) {
+                            return 'SUCCESS';
+                        }
+                    }
+                }
+            }
+        }
+        return 'FAILED';
+    }
+
+    /**
+     * 生成订单号
+     */
+    public function generateTradeNo()
+    {
+        return $this->msgSrcId . date("YmdHis") . substr(uniqid(), 0, 12);
+    }
+
+    private function makeSign(array $data)
+    {
+        //签名步骤一:按字典序排序参数
+        ksort($data);
+        $buff = "";
+        foreach ($data as $k => $v) {
+            if ($k != "sign" && $v != "" && !is_array($v)) {
+                $buff .= $k . "=" . $v . "&";
+            }
+        }
+        $buff = trim($buff, "&");
+        //签名步骤二:在string后加入KEY
+        $string = $buff . $this->key;
+        //签名步骤三:MD5加密
+        $string = md5($string);
+        //签名步骤四:所有字符转为大写
+        $result = strtoupper($string);
+        return $result;
+    }
+}

+ 54 - 42
app/Libs/Pay/WechatPay.php

@@ -11,51 +11,63 @@ use App\Libs\Pay\Merchants\Palmpay;
 use App\Libs\Pay\Merchants\PalmpayV2;
 use App\Libs\Pay\Merchants\OriginBank;
 use App\Libs\Pay\Merchants\SmkPay;
+use App\Libs\Pay\Merchants\UnionPay;
 
-class WechatPay 
+/**
+ * @method \App\Libs\Pay\Merchants\UnionPay Union(array $config)
+ * @method \App\Libs\Pay\Merchants\Official Official(array $config)
+ */
+class WechatPay
 {
-	private static $_instance;
-
-	static function instance($merchant,$config=[])
+	static function instance($merchant, array $config = [])
 	{
-		if(!self::$_instance)
-		{
-			switch ($merchant) {
-				//case 'Swiftpass':'SWIFTPASS'
-				case 'SWIFTPASS':
-					self::$_instance = new Swiftpass();
-					break;
-				//case 'Youluo':
-				case 'YOULUO':
-					self::$_instance = new Youluo();
-					break;
-				case 'ALLINPAY':
-					self::$_instance = new AllinPay($config);
-					break;
-                case 'OFFICIALPAY':
-                    self::$_instance = new Official($config);
-                    break;
-                case 'LIANLIANPAY':
-                    self::$_instance = new LianLianPay($config);
-                    break;
-                case 'PALMPAY':
-                    self::$_instance = new Palmpay($config);
-                    break;
-                case 'PALMPAYV2':
-                    self::$_instance = new PalmpayV2($config);
-                    break;
-                case 'ORIGINBANK':
-                    self::$_instance = new OriginBank($config);
-                    break;
-                case 'SMKPAY':
-                    self::$_instance = new SmkPay($config);
-                    break;
-                default:
-                    return null;
-			}
-			
+		switch ($merchant) {
+			case 'SWIFTPASS':
+				$instance = new Swiftpass();
+				break;
+			case 'YOULUO':
+				$instance = new Youluo();
+				break;
+			case 'ALLINPAY':
+				$instance = new AllinPay($config);
+				break;
+			case 'OFFICIALPAY':
+				$instance = new Official($config);
+				break;
+			case 'LIANLIANPAY':
+				$instance = new LianLianPay($config);
+				break;
+			case 'PALMPAY':
+				$instance = new Palmpay($config);
+				break;
+			case 'PALMPAYV2':
+				$instance = new PalmpayV2($config);
+				break;
+			case 'ORIGINBANK':
+				$instance = new OriginBank($config);
+				break;
+			case 'SMKPAY':
+				$instance = new SmkPay($config);
+				break;
+			case 'UNIONPAY':
+				$instance = new UnionPay($config);
+				break;
+			default:
+				return null;
 		}
-		return self::$_instance;
+		return $instance;
 	}
 
-}
+	/**
+	 * Dynamically pass methods to the application.
+	 *
+	 * @param string $name
+	 * @param array  $arguments
+	 *
+	 * @return mixed
+	 */
+	public static function __callStatic($name, $arguments)
+	{
+		return self::instance($name, ...$arguments);
+	}
+}