dever 6 years ago
parent
commit
16a218f0b1
7 changed files with 490 additions and 0 deletions
  1. 155 0
      lib/Cmbc.php
  2. 7 0
      sdk/cmbc.php
  3. 100 0
      sdk/cmbc/Api/Core.php
  4. 53 0
      sdk/cmbc/Api/Notify.php
  5. 94 0
      sdk/cmbc/Api/UnifiedOrder.php
  6. 22 0
      sdk/cmbc/Handle.php
  7. 59 0
      sdk/cmbc/Setting.php

+ 155 - 0
lib/Cmbc.php

@@ -0,0 +1,155 @@
+<?php namespace Pay\Lib;
+use Dever;
+Dever::apply('sdk/cmbc', 'pay');
+
+class Cmbc extends Core
+{
+	public function __construct($config)
+	{
+		$project = Dever::project('pay');
+		$this->config = new \Cmbc\Setting();
+		# 通知接口
+		$config['notify'] = $this->url($config['type'], $config['id']);
+		# 证书
+		$config['ssl'] = array
+		(
+			'cert' => $config['file_cert'],
+			'key' => $config['file_key'],
+		);
+
+		$this->config->set($config['appid'], $config['appsecret'], $config['mchid'], $config['notify'], $config['key'], $config['ssl'], $config['type'], $config['timeout']);
+	}
+
+	/**
+	 * 通知
+	 */
+	public function notify()
+	{
+		$this->log('支付回调-初始化', file_get_contents("php://input"));
+		$tools = new \Cmbc\Handle();
+		$callback = $tools->get('notify', $this->config);
+		$result = $callback->request(Dever::input(), $this);
+		print_r($result);die;
+		$this->log('支付回调-获取数据', $result);
+		$this->updateOrder($result['mhtOrderNo'], $result['mhtOrderAmt'], $msg);
+	}
+
+	/**
+	 * 获取统一下单的基本信息
+	 */
+	public function order($account_id, $uid, $username, $product_id, $name, $cash, $openid = false, $type = 1, $order_id = false)
+	{
+		$trade_type = $this->getType($type);
+		$order_id = $this->createOrder($uid, $username, $account_id, $product_id, $name, $cash, $this->config->getType(), $order_id);
+		$tools = new \Cmbc\Handle();
+
+		$order = $tools->get('order', $this->config);
+
+		$request['mhtOrderNo'] = $order_id;
+		$request['mhtOrderName'] = $name;
+		$request['mhtOrderAmt'] = $cash * 100;
+		$request['mhtOrderDetail'] = $name;
+		$request['mhtOrderStartTime'] = date("YmdHis");
+		$request['notifyUrl'] = $this->config->getNotifyUrl();
+		$request['outputType'] = 1;
+		$request['mhtSubAppId'] = '?';
+		$request['consumerId'] = $openid;
+
+		$result = $order->request($request);
+		print_r($result);die;
+		$this->updateOrderParam($order_id, $result);
+		return $result;
+	}
+
+	/**
+	 * 获取二维码支付
+	 */
+	public function qrcode($order, $refer)
+	{
+		$notify = new \NativePay();
+		$result = $notify->GetPayUrl($order);
+		$url = $result['code_url'];
+		return $url;
+	}
+
+	/**
+	 * 获取小程序支付
+	 */
+	public function applet($order)
+	{
+		if (isset($order['prepay_id'])) {
+
+			$string = 'appId='.$this->config->getAppId().'&nonceStr='.$order['nonce_str'].'&package=prepay_id='.$order['prepay_id'].'&signType='.$order['sign_type'].'&timeStamp='.$order['time'].'&key='.$this->config->getKey();
+			if($order['sign_type'] == "MD5"){
+				$string = md5($string);
+			} else {
+				$string = hash_hmac("sha256", $string, $this->config->getKey());
+			}
+
+			$order['sign'] = $string;
+		}
+		return $order;
+	}
+
+
+	/**
+	 * 获取页面支付
+	 */
+	public function page($order, $refer)
+	{
+		$refer = urldecode($refer);
+		$tools = new \JsApiPay($this->config);
+		$info = $tools->GetJsApiParameters($order);
+
+		$html = '<script type="text/javascript">
+		function jsApiCall()
+		{
+			WeixinJSBridge.invoke(
+				"getBrandWCPayRequest",
+				'.$info.',
+				function(res){
+					//WeixinJSBridge.log(res.err_msg);
+					if(res.err_msg == "get_brand_wcpay_request:ok")
+					{
+						location.href = "'.$refer.'";
+					} else {
+						alert(res.err_code+res.err_desc+res.err_msg);
+					}
+				}
+			);
+		}
+
+		function callpay()
+		{
+			if (typeof WeixinJSBridge == "undefined"){
+			    if( document.addEventListener ){
+			        document.addEventListener("WeixinJSBridgeReady", jsApiCall, false);
+			    }else if (document.attachEvent){
+			        document.attachEvent("WeixinJSBridgeReady", jsApiCall); 
+			        document.attachEvent("onWeixinJSBridgeReady", jsApiCall);
+			    }
+			}else{
+			    jsApiCall();
+			}
+		}
+		callpay();
+		</script>';
+
+		return $html;
+	}
+
+	private function getType($type)
+	{
+		switch ($type) {
+			case 1:
+				$type = 'JSAPI';
+				break;
+			
+			case 2:
+				$type = 'NATIVE';
+				break;
+		}
+
+		return $type;
+	}
+}

+ 7 - 0
sdk/cmbc.php

@@ -0,0 +1,7 @@
+<?php
+
+Dever::apply('sdk/cmbc/Setting', 'pay');
+Dever::apply('sdk/cmbc/Handle', 'pay');
+Dever::apply('sdk/cmbc/Api/Core', 'pay');
+Dever::apply('sdk/cmbc/Api/UnifiedOrder', 'pay');
+Dever::apply('sdk/cmbc/Api/Notify', 'pay');

+ 100 - 0
sdk/cmbc/Api/Core.php

@@ -0,0 +1,100 @@
+<?php
+namespace Cmbc\Api;
+
+use Cmbc\Setting;
+
+abstract class Core
+{
+	protected $param = array();
+	protected $data = array();
+	protected $setting = null;
+	protected $error = array();
+	protected $method = 'post';
+	abstract protected function init();
+	abstract public function request($request, $tool = false);
+	abstract public function response($response);
+
+	public function __construct(Setting $setting)
+	{
+		$this->setting = $setting;
+		$this->init();
+		$this->param['appId'] = $this->setting->getAppId();
+		$this->param['mhtSubMchId'] = $this->setting->getSubMchId();
+	}
+
+	protected function setParam($key, $default = false, $isMust = true)
+	{
+		if (!$this->data) {
+			$this->setError('param data is not exists');
+		} else {
+			if (!isset($this->data[$key]) && $default) {
+				$this->data[$key] = $default;
+			}
+			if (isset($this->data[$key])) {
+				if (!$this->data[$key] || $this->data[$key] == 0) {
+					if ($default) {
+						$this->data[$key] = $default;
+					}
+				}
+				if ($isMust == true && !$this->data[$key] && $this->data[$key] != 0) {
+					$this->setError('param data ['.$key.'] is not value');
+				}
+				$this->param[$key] = $this->data[$key];
+			}
+		}
+
+		return $this;
+	}
+
+	protected function createSignature($type = 'MD5')
+	{
+		ksort($this->param);
+		$signature_string = '';
+		foreach ($this->param as $k => $v) {
+			if ($v || $v == 0) {
+				$signature_string .= $k . '=' . $v . '&';
+			}
+		}
+		$signature_string = substr($signature_string, 0, -1);
+		$method = strtoupper($type);
+		$secret = $method($this->setting->getAppSecret());
+		return $method($signature_string . '&' . $secret);
+	}
+
+	protected function curl()
+	{
+		$curl = curl_init();
+		curl_setopt($curl, CURLOPT_URL, $this->api);
+		curl_setopt($curl, CURLOPT_HEADER, false);
+		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+		if ($this->method == 'post' && $this->param) {
+			curl_setopt($curl, CURLOPT_POST, 1);
+			curl_setopt($curl, CURLOPT_POSTFIELDS, $this->param);
+		}
+		
+		$data = curl_exec($curl);
+		curl_close($curl);
+		parse_str($data, $result);
+		if (isset($result['responseCode']) && $result['responseCode'] == 'A002') {
+			# 失败
+			
+		}
+		print_r($result);die;
+		return false;
+	}
+
+	protected function setError($msg)
+	{
+		$this->error[] = $msg;
+	}
+
+	protected function getError()
+	{
+		$number = count($this->error);
+		if ($number > 0) {
+			$msg = $this->error[0];
+			return $msg;
+		}
+		return false;
+	}
+}

+ 53 - 0
sdk/cmbc/Api/Notify.php

@@ -0,0 +1,53 @@
+<?php
+namespace Cmbc\Api;
+
+class Notify extends Core
+{
+	protected function init()
+	{
+		$this->api = 'https://ipaynow.acquire.cmbchina.com/';
+		$this->param['funcode'] = 'WP001';
+		$this->param['version'] = '1.0.0';
+	}
+
+	public function request($request, $tool = false)
+	{
+		$this->data = $request;
+		$this->setParam('mhtOrderNo');
+		$this->setParam('mhtOrderName');
+		$this->setParam('mhtOrderType');
+		$this->setParam('mhtCurrencyType');
+		$this->setParam('mhtOrderAmt');
+		$this->setParam('oriMhtOrderAmt');
+		$this->setParam('discountAmt');
+		$this->setParam('mhtOrderDetail');
+		$this->setParam('mhtOrderTimeOut');
+		$this->setParam('mhtOrderStartTime');
+		$this->setParam('payTime');
+		$this->setParam('nowPayOrderNo');
+		$this->setParam('transStatus');
+		$this->setParam('mhtCharset');
+		$this->setParam('deviceType');
+		$this->setParam('payChannelType');
+		$this->setParam('channelOrderNo');
+		$this->setParam('payConsumerId');
+		$this->setParam('mhtReserved');
+		$this->setParam('bankType');
+		$this->setParam('cardType');
+		$this->setParam('signType');
+		$error = $this->getError();
+		if ($error) {
+			return $tool->updateOrder($this->param['mhtOrderNo'], $this->param['mhtOrderAmt'], $error);
+		}
+		$signature = $this->createSignature($this->param['signType']);
+		if ($signature != $data['signature']) {
+			$tool->updateOrder($this->param['mhtOrderNo'], $this->param['mhtOrderAmt'], '签名错误');
+		}
+		return $this->param;
+	}
+
+	public function response($response)
+	{
+		return $response;
+	}
+}

+ 94 - 0
sdk/cmbc/Api/UnifiedOrder.php

@@ -0,0 +1,94 @@
+<?php
+namespace Cmbc\Api;
+
+class UnifiedOrder extends Core
+{
+	protected function init()
+	{
+		$this->api = 'https://ipaynow.acquire.cmbchina.com/';
+		$this->param['funcode'] = 'WP001';
+		$this->param['version'] = '1.0.0';
+	}
+
+	/**
+	 * mhtOrderNo 订单号
+	 * mhtOrderName 商品名
+	 * mhtOrderType 交易类型:01普通消费 05代理消费
+	 * mhtCurrencyType 156人民币
+	 * mhtOrderAmt 用户实付金额 单位(人民币):分 整数,无小数点
+	 * oriMhtOrderAmt 订单原始金额
+	 * discountAmt 订单优惠金额
+	 * mhtOrderDetail 商户订单详情
+	 * mhtOrderTimeOut 商户订单超时时间
+	 * mhtOrderStartTime 商户订单开始时间
+	 * notifyUrl 商户后台通知URL HTTP协议或者HTTPS协议,POST方式提交报文。
+	 * frontNotifyUrl 商户前台通知URL HTTP协议或者HTTPS协议,POST方式提交报文。outputType=0时必填
+	 * mhtCharset 商户字符编码
+	 * deviceType 设备类型 14小程序
+	 * payChannelType 用户所选渠道类型 13微信
+	 * mhtReserved 商户保留域
+	 * outputType 输出格式 0 直接调起支付 1 返回支付凭证
+	 * mhtSubAppId 商户appId
+	 * consumerId 消费者ID
+	 * mhtLimitPay 是否支持信用卡支付 定值:
+0表示支付不限制卡类型
+1表示不能使用信用卡支付 
+
+	 * mhtGoodsTag 商户签名方法
+	 * mhtSignType 商户保留域
+
+	 */
+	public function request($request, $tool = false)
+	{
+		$this->data = $request;
+		$this->setParam('mhtOrderNo');
+		$this->setParam('mhtOrderName');
+		$this->setParam('mhtOrderType', '01');
+		$this->setParam('mhtCurrencyType', '156');
+		$this->setParam('mhtOrderAmt');
+		$this->setParam('oriMhtOrderAmt', false, false);
+		$this->setParam('discountAmt', false, false);
+		if (!isset($this->param['oriMhtOrderAmt']) && isset($this->param['mhtOrderAmt'])) {
+			$this->param['oriMhtOrderAmt'] = $this->param['mhtOrderAmt'];
+		}
+		if (!isset($this->param['discountAmt']) && isset($this->param['mhtOrderAmt'])) {
+			$this->param['discountAmt'] = $this->param['mhtOrderAmt'];
+		}
+
+		$this->setParam('mhtOrderDetail');
+		$this->setParam('mhtOrderTimeOut', $this->setting->getTimeOut());
+		$this->setParam('mhtOrderStartTime', date("YmdHis"));
+		$this->setParam('notifyUrl');
+		$this->setParam('frontNotifyUrl', false, false);
+		$this->setParam('mhtCharset', 'UTF-8');
+		$this->setParam('deviceType', 14);
+		$this->setParam('payChannelType', 13);
+		$this->setParam('mhtReserved', false, false);
+		$this->setParam('outputType', 0);
+		if (isset($this->param['outputType']) && $this->param['outputType'] == 1 && $this->param['payChannelType'] == 13) {
+			$this->setParam('mhtSubAppId');
+		} else {
+			$this->setParam('mhtSubAppId', false, false);
+		}
+		if (isset($this->param['outputType']) && $this->param['outputType'] == 1) {
+			$this->setParam('consumerId');
+		} else {
+			$this->setParam('consumerId', false, false);
+		}
+		$this->setParam('mhtLimitPay', 1);
+		$this->setParam('mhtGoodsTag', false, false);
+		$this->setParam('mhtSignType', 'MD5');
+		$error = $this->getError();
+		if ($error) {
+			return $error;
+		}
+		$this->param['mhtSignature'] = $this->createSignature($this->param['mhtSignType']);
+		$response = $this->curl();
+		return $this->response($response);
+	}
+
+	public function response($response)
+	{
+		return $response;
+	}
+}

+ 22 - 0
sdk/cmbc/Handle.php

@@ -0,0 +1,22 @@
+<?php
+namespace Cmbc;
+
+class Handle
+{
+	public function get($method, $setting)
+	{
+		$class = $this->config($method);
+		$class = new $class($setting);
+		return $class;
+	}
+
+	private function config($method)
+	{
+		$config['order'] = '\\Cmbc\\Api\\UnifiedOrder';
+		$config['notify'] = '\\Cmbc\\Api\\Notify';
+
+		if (isset($config[$method])) {
+			return $config[$method];
+		}
+	}
+}

+ 59 - 0
sdk/cmbc/Setting.php

@@ -0,0 +1,59 @@
+<?php
+namespace Cmbc;
+
+class Setting
+{
+	public function set($appid, $appsecret, $submchid, $notify, $key, $ssl, $type, $timeout = 600)
+	{
+		$this->appid = $appid;
+		$this->appsecret = $appsecret;
+		$this->submchid = $submchid;
+
+		$this->notify = $notify;
+		$this->key = $key;
+		$this->ssl = $ssl;
+		$this->type = $type;
+		$this->timeout = $timeout;
+		
+		return $this;
+	}
+
+	public function getNotifyUrl()
+	{
+		return $this->notify;
+	}
+
+	public function getSSLCertPath(&$sslCertPath, &$sslKeyPath)
+	{
+		$sslCertPath = $this->ssl['cert'];
+		$sslKeyPath = $this->ssl['key'];
+	}
+	public function getTimeOut()
+	{
+		return $this->timeout;
+	}
+	public function getType()
+	{
+		return $this->type;
+	}
+
+	public function getAppId()
+	{
+		return $this->appid;
+	}
+
+	public function getAppSecret()
+	{
+		return $this->appsecret;
+	}
+
+	public function getSubMchId()
+	{
+		return $this->submchid;
+	}
+
+	public function getKey()
+	{
+		return $this->key;
+	}
+}