微信支付 - 统一下单 - 生成预订单
包含
1. 公众号支付 wiki:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
2. App支付 wiki:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
@param array $conf 配置数组
@return bool|mixed
547120
public function wxPayUnifiedOrder($conf = [])
    {

        // [必填]公众账号ID、应用ID
        $conf['appid'] = $this->appId;

        // [必填]商户号、
        $conf['mch_id'] = $this->mchId;

        // 设备号
        // - device_info

        // [必填]nonce_str 随机字符串
        $conf['nonce_str'] = SHA1::get_random_str(32);

        // 签名类型
        $conf['sign_type'] = 'MD5';

        // [必填]商品描述
        // - body

        // 商品详情
        // - detail

        // 附加数据
        // - attach

        // [必填]商户订单号
        // - out_trade_no

        // 货币类型
        // - fee_type

        // [必填]总金额
        // - total_fee

        // [必填]终端IP
        $conf['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];

        // 交易起始时间
        // - time_start

        // 交易结束时间
        // - time_expire

        // 商品标记
        // - goods_tag

        // [必填]通知地址
        // - notify_url

        // [必填]交易类型
        // - trade_type

        // 指定支付方式
        // - limit_pay

        // 用户标识, trade_type=JSAPI时（即公众号支付），此参数必传
        // - openid

        // [必填]签名
        $conf['sign'] = SHA1::getSign2($conf, 'key='.$this->key);

        // 生成xml
        $xml = Xml::toXml($conf);

        // 调用接口
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        try {
            $res = HttpCurl::post($url, $xml);
            libxml_disable_entity_loader(true);
            return json_decode(json_encode(simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        } catch (\Exception $e) {
            return false;
        }
    }
142909
public function write($buf = null)
    {
        if ($buf === null) {
            if ($this->proxyState > 0) {
                return $this->proxyWrite();
            }
            $len = 0;
            if ($this->hasDataToWrite()) {
                $buf = $this->outLen > 0 ? substr($this->outBuf, $this->outLen) : $this->outBuf;
                $len = $this->write($buf);
                if ($len !== false) {
                    $this->outLen += $len;
                }
            }
            return $len;
        }
        $n = @fwrite($this->sock, $buf);
        if ($n === 0 && $this->ioEmptyError()) {
            $n = false;
        }
        $this->ioFlagReset();
        return $n;
    }
1297599
public function QPayRefund($params = array()){
        /*  入参
            $params = array();
            $params["out_trade_no"] = "20160512161914_BBC";
            $params["sub_mch_id"] = "1900005911";
            $params["out_refund_no"] = "20160512161914_BBC_out_refund_1";
            $params["refund_fee"] = "99999";
            $params["op_user_id"] = "1900005911";
            $params["op_user_passwd"] = "";*/
        if (empty($params["out_trade_no"])){
            throw new Exception('商户订单号参数不能缺少' ,'OUT_TRADE_NO_MUST_INPUT');
        }
//        if (empty($params["sub_mch_id"])){
//            throw new Exception('货币类型不能缺少' ,'FEE_TYPE');
//        }
        if (empty($params["op_user_id"])){
            throw new Exception('订单金额不能缺少' ,'TOTAL_FEE');
        }
        if (empty($params["op_user_passwd"])){
            throw new Exception('终端IP不能缺少' ,'SPBILL_CREATE_IP');
        }
        if (empty($params["out_refund_no"])){
            throw new Exception('退款单号能缺少' ,'SPBILL_CREATE_IP');
        }
        if (empty($params["refund_fee"])){
            throw new Exception('退款金额不能缺少' ,'SPBILL_CREATE_IP');
        }
        //api调用
        $qpayApi = new QpayMchAPI('https://api.qpay.qq.com/cgi-bin/pay/qpay_refund.cgi', true, 10);
        $qpayApi->setMchId($params['mchId']);
        $qpayApi->setMchKey('8525638f86969d1de5c51ad0494f4f13');
        $qpayApi->setIsSSL(true);
        $qpayApi->setCertFilePath('/Users/aji/documents/Project/sicmouse-api/app/apiclient_cert.pem');
        $qpayApi->setKeyFilePath('/Users/aji/documents/Project/sicmouse-api/app/apiclient_key.pem');
        $ret = $qpayApi->reqQpay($params);
        return QpayMchUtil::xmlToArray($ret);
    }
24509
public function load($file, $marge_config = FALSE) {

		$config = null;

		$file_path = APP_CONFIG_PATH . $file . '.php';
		
		if (in_array($file_path, $this->is_loaded, TRUE)) {
			return $this->sections_config[$file];
		} else {
			//没有加载，则开始加载
			if (file_exists($file_path)) {
				$found = TRUE;
				try {
					$config = include ($file_path);
				} catch(\Exception $exp) {
					$config = [];
				}
			}

			if (isset($this->sections_config[$file])) {
				$this->sections_config[$file] = array_merge($this->sections_config[$file], $config);
			} else {
				$this->sections_config[$file] = $config;
			}
			if ($marge_config === TRUE) {
				$this->config = array_merge($this->config, $config);
			}
			
			$this->is_loaded[] = $file_path;
		}
		
		if ($config === null || !is_array($config)) {
			throw new Exception('Your ' . $file_path . ' file does not appear to contain a valid configuration array.');
		}
		
		return $config;
	}
1263474
public function translateBackup($type, array $conf)
    {
        /** @var \phpbu\App\Configuration\Backup $backup */
        $backup = $this->{$this->types[$type]}($conf);
        $backup->setTarget($this->translateTarget($conf['target']));

        $this->addChecksIfConfigured($backup, $conf);
        $this->addSyncIfConfigured($backup, $conf);
        $this->addCleanupIfConfigured($backup, $conf);
        $this->addCryptIfConfigured($backup, $conf);

        return $backup;
    }
481238
private function file($config = array()) {
        $filePath = $config['filePath'];

        if (!file_exists($filePath)) {
            Filesystem::mkdir($filePath);
        }
        //初始化缓存路径
        CacheManager::setup(array(
            "path" => isset($filePath) ? $filePath : sys_get_temp_dir(), // or in windows "C:/tmp/"
        ));
        CacheManager::CachingMethod("phpfastcache");

        //初始化缓存
        $InstanceCache = CacheManager::Files();

        return $InstanceCache;
    }
516032
private function buildConnection($connConfig) {
        //基于数组的连接配置
        if (is_array($connConfig)) {
            $pdoProviderClass = $connConfig['pdoProvider'];
            unset($connConfig['pdoProvider']);

            /* @var $conn PDOProviderInterface */
            $pdoProvider = new $pdoProviderClass($connConfig);

            $conn = new Connection($pdoProvider, $this->logger);
            $conn->setTablePrefix($connConfig['tablePrefix']);
        }
        //回调函数
        //回调函数可以接收当前 ConnectionManager 实例作为参数，当然，这个参数是可选的
        elseif ($connConfig instanceof Closure) {
            $callback = $connConfig;
            $refFunc = new ReflectionFunction($callback);
            $conn = $refFunc->getNumberOfParameters() == 1 ? $callback($this) : $callback();
        } else {
            throw new SqlException('连接配置类型错误');
        }

        return $conn;
    }
847993
public function set($alias, $value, $config = array())
	{
		// 打开或创建缓存文件
		$fp = fopen($this->getFileName($alias), 'w');
		if (false === $fp)
		{
			return false;
		}
		else
		{
			// 写锁
			if (flock($fp, LOCK_EX))
			{
				if(isset($config['raw']) && $config['raw'])
				{
					fwrite($fp, $value);
				}
				else 
				{
					// 防止泄露数据
					fwrite($fp, '<?php exit;?>');
					// 写入有效期
					fwrite($fp, sprintf('%012d', isset($config['expire']) ? $config['expire'] : 0));
					// 写入序列化后的值
					fwrite($fp, serialize($value));
				}
				$result = true;
			}
			else
			{
				$result = false;
			}
			// 关闭文件
			fclose($fp);
			return $result;
		}
	}
1297027
public function makeSign()
	{
		//签名步骤一：按字典序排序参数
		ksort($this->values);
		$string = $this->toUrlParams();
		//签名步骤二：在string后加入KEY
		$string = $string . '&key=' . Wxpay::getConfig('key');
		//签名步骤三：MD5加密
		$string = md5($string);
		//签名步骤四：所有字符转为大写
		$result = strtoupper($string);
		return $result;
	}
1280624
public function main($content = '', $conf = [])
    {
        // first we have to take care of possible flexform values containing additional information
        // that is not available via DB relations. It will be added as "virtual" key to the existing data Array
        // so that you can easily get the values with TypoScript
        $this->initPluginFlexForm();
        $this->getPluginFlexFormData();

        $this->languageAspect = GeneralUtility::makeInstance(Context::class)->getAspect('language');

        // now we have to find the children of this grid container regardless of their column
        // so we can get them within a single DB query instead of doing a query per column
        // but we will only fetch those columns that are used by the current grid layout
        if ($this->languageAspect->getLegacyOverlayType() && $this->cObj->data['l18n_parent']) {
            $element = $this->cObj->data['l18n_parent'];
        } else {
            $element = $this->cObj->data['uid'];
        }
        $pid = $this->cObj->data['pid'];
        $layout = $this->cObj->data['tx_gridelements_backend_layout'];

        /** @var LayoutSetup $layoutSetup */
        $layoutSetup = GeneralUtility::makeInstance(LayoutSetup::class);
        $layoutSetup->init($this->cObj->data['pid'], $conf);

        $availableColumns = $layoutSetup->getLayoutColumns($layout);
        $csvColumns = ltrim(str_replace('-2,-1', '', $availableColumns['CSV']), ',');
        $this->getChildren($element, $pid, $csvColumns);

        // and we have to determine the frontend setup related to the backend layout record which is assigned to this container
        $typoScriptSetup = $layoutSetup->getTypoScriptSetup($layout);

        // we need a sorting columns array to make sure that the columns are rendered in the order
        // that they have been created in the grid wizard but still be able to get all children
        // within just one SELECT query
        $sortColumns = explode(',', $csvColumns);

        $this->renderChildrenIntoParentColumns($typoScriptSetup, $sortColumns);
        unset($children);
        unset($sortColumns);

        // if there are any columns available, we can go on with the render process
        if (!empty($this->cObj->data['tx_gridelements_view_columns'])) {
            $content = $this->renderColumnsIntoParentGrid($typoScriptSetup);
        }

        unset($availableColumns);
        unset($csvColumns);

        if (isset($typoScriptSetup['jsFooterInline']) || isset($typoScriptSetup['jsFooterInline.'])) {
            $jsFooterInline = isset($typoScriptSetup['jsFooterInline.']) ? $this->cObj->stdWrap(
                $typoScriptSetup['jsFooterInline'],
                $typoScriptSetup['jsFooterInline.']
            ) : $typoScriptSetup['jsFooterInline'];

            $this->getPageRenderer()->addJsFooterInlineCode('gridelements' . $element, $jsFooterInline);
            unset($typoScriptSetup['jsFooterInline']);
            unset($typoScriptSetup['jsFooterInline.']);
        }

        // finally we can unset the columns setup as well and apply stdWrap operations to the overall result
        // before returning the content
        unset($typoScriptSetup['columns.']);

        return !empty($typoScriptSetup) ? $this->cObj->stdWrap($content, $typoScriptSetup) : $content;
    }
925711
function with($apikey, array $conf = []) {
        if (!empty($conf)) foreach ($conf as $key => $value) {
            $this->conf[$key] = $value;
        }
        
        if (isset($apikey)) $this->conf[self::YP_APIKEY] = $apikey;
        
        return $this;
    }
878783
public static function cpf(string $cpf): bool
    {
        $cpf = preg_replace('/[^0-9]/', '', (string)$cpf);
        if (strlen($cpf) !== 11 || $cpf === '00000000000' || $cpf === '11111111111' || $cpf === '22222222222' || $cpf === '33333333333' || $cpf === '44444444444' || $cpf === '55555555555' || $cpf === '66666666666' || $cpf === '77777777777' || $cpf === '88888888888' || $cpf === '99999999999'):
            return false;
        endif;

        for ($i = 0, $j = 10, $soma = 0; $i < 9; $i++, $j--):
            $soma += $cpf{$i} * $j;
        endfor;

        $resto = $soma % 11;
        if ($cpf{9} != ($resto < 2 ? 0 : 11 - $resto)):
            return false;
        endif;

        for ($i = 0, $j = 11, $soma = 0; $i < 10; $i++, $j--):
            $soma += $cpf{$i} * $j;
        endfor;

        $resto = $soma % 11;
        return $cpf{10} == ($resto < 2 ? 0 : 11 - $resto);

    }
1282789
public function getWxPayJsApiParameters($prepayId)
    {
        // 获取jsapi支付的参数
        $input = [
            //微信分配的公众账号ID WxPayConfig::APPID
            'appId' => $this->appId,
            //设置支付时间戳
            'timeStamp' => (string)time(),
            //随机字符串
            'nonceStr' => SHA1::get_random_str(32),
            //订单详情扩展字符串
            'package' => 'prepay_id='.$prepayId,
            //签名方式
            'signType' => 'MD5',
        ];
        // 签名
        $input['paySign'] = SHA1::getSign2($input, 'key='.$this->key);
        return json_encode($input);
    }
825347
public function QPayMicroPay($params = array()){
      //入参q
/*      $params["out_trade_no"] = "20160512161914_BBC" . "A";
      $params["sub_mch_id"] = "1900005911";
      $params["body"] = "body_test_中文";
      $params["device_info"] = "WP00000001";
      $params["fee_type"] = "CNY";
      $params["notify_url"] = "https://10.222.146.71:80/success.xml";
      $params["spbill_create_ip"] = "127.0.0.1";
      $params["total_fee"] = "1";
      $params["trade_type"] = "MICROPAY";
      $params["auth_code"] = "910728310408849937";*/
//      if (empty($params["out_trade_no"])){
//          throw new Exception('商户订单号参数不能缺少' ,'OUT_TRADE_NO_MUST_INPUT');
//      }
//      if (empty($params["fee_type"])){
//          throw new Exception('货币类型不能缺少' ,'FEE_TYPE');
//      }
//      if (empty($params["total_fee"])){
//          throw new Exception('订单金额不能缺少' ,'TOTAL_FEE');
//      }
//      if (empty($params["spbill_create_ip"])){
//          throw new Exception('终端IP不能缺少' ,'SPBILL_CREATE_IP');
//      }
//      if (empty($params["device_info"])){
//          throw new Exception('设备号不能缺少' ,'DEVICE_INFO');
//      }
//      if (empty($params["auth_code"])){
//          throw new Exception('付款码不能缺少' ,'AUTH_CODE');
//      }
/*      if (empty($params["sub_mch_id"])){
          throw new Exception('' ,'SUB_MCH_ID');
      }*/
/*      if (empty($params["notify_url"])){
          throw new Exception('' ,'NOTIFY_URL');
      }*/
//      if (empty($params["body"])){
//          throw new Exception('商品描述' ,'BODY');
//      }
//      if (empty($params["trade_type"])){
//          throw new Exception('支付场景不能缺少' ,'TRADE_TYPE');
//      }
    //api调用
      $qpayApi = new QpayMchAPI('https://qpay.qq.com/cgi-bin/pay/qpay_micro_pay.cgi', null, 10);
      $qpayApi->setMchId($params['mchId']);
      $qpayApi->setMchKey($params['mchKey']);
      unset($params['mchId'], $params['mchKey']);
      $ret = $qpayApi->reqQpay($params);

      return QpayMchUtil::xmlToArray($ret);
    }
1232613
public function del_kf($kf_account)
    {
        $url = self::API_DOMAIN . 'customservice/kfaccount/del?access_token=' . $this->get_access_token() . '&kf_account=' . $kf_account;
        $res = HttpCurl::get($url, 'json');
        // 异常处理: 获取时网络错误
        if ($res === false) {
            return Error::code('ERR_GET');
        }        
        // 判断是否调用成功
        if ($res->errcode == 0) {
            return array(null, true);
        } else {
            return array($res, null);
        }
    }
1162774
public function main($content, $conf)
    {
        $this->ms = GeneralUtility::milliseconds();

        $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
        $this->conf = $typoScriptService->convertTypoScriptArrayToPlainArray($conf);
        $this->pi_setPiVarDefaults();

        // use pi1 locallang values, since all the frontend locallang values for
        // pi1, pi2 are set in pi1 language file
        $this->pi_loadLL('EXT:ke_search/Resources/Private/Language/locallang_searchbox.xml');

        // Configuring so caching is not expected. This value means that no cHash params are ever set.
        // We do this, because it's a USER_INT object!
        $this->pi_USER_INT_obj = 1;

        // initializes plugin configuration
        $this->init();

        if ($this->conf['resultPage'] != $GLOBALS['TSFE']->id) {
            $content = '<div id="textmessage">' . $this->pi_getLL('error_resultPage') . '</div>';
            return $this->pi_wrapInBaseClass($content);
        }

        // init template
        $this->initFluidTemplate();

        // hook for initials
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'])) {
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['initials'] as $_classRef) {
                $_procObj = &GeneralUtility::makeInstance($_classRef);
                $_procObj->addInitials($this);
            }
        }

        // assign isEmptySearch to fluid templates
        $this->fluidTemplateVariables['isEmptySearch'] = $this->isEmptySearch;

        // render "no results"-message, "too short words"-message and finally the result list
        $this->getSearchResults();

        // number of results
        $this->fluidTemplateVariables['numberofresults'] = $this->numberOfResults;

        // render links for sorting, fluid template variables are filled in class Sorting
        $this->renderOrdering();

        // process query time
        $queryTime = (GeneralUtility::milliseconds() - $GLOBALS['TSFE']->register['ke_search_queryStartTime']);
        $this->fluidTemplateVariables['queryTime'] = $queryTime;
        $this->fluidTemplateVariables['queryTimeText'] = sprintf($this->pi_getLL('query_time'), $queryTime);

        // render pagebrowser
        if ($GLOBALS['TSFE']->id == $this->conf['resultPage']) {
            if ($this->conf['pagebrowserOnTop'] || $this->conf['pagebrowserAtBottom']) {
                $this->renderPagebrowser();
            }
        }

        // hook: modifyResultList
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyResultList'])) {
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ke_search']['modifyResultList'] as $_classRef) {
                $_procObj = &GeneralUtility::makeInstance($_classRef);
                $_procObj->modifyResultList($this->fluidTemplateVariables, $this);
            }
        }

        // generate HTML output
        $this->resultListView->assignMultiple($this->fluidTemplateVariables);
        $htmlOutput = $this->resultListView->render();

        return $htmlOutput;
    }
523488
protected function getContentObjectVariables(array $conf = array())
    {
        // Call Parent Function to maintain core functions
        $variables = parent::getContentObjectVariables($conf);

        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
        $this->inlineHelper = $objectManager->get(InlineHelper::class);

        // Make some enhancements to data
        $data = $variables['data'];
        $this->inlineHelper->addFilesToData($data, "pages");
        $this->inlineHelper->addIrreToData($data, "pages");
        $variables['data'] = $data;

        return $variables;
    }