* @date 2020-01-22 22:37:21 */ declare(strict_types=1); namespace App\Repositories\Service\Payment; use Hyperf\Guzzle\ClientFactory; abstract class PaymentInterface { protected static $_self = array(); protected $_lastError = null; /** * 根据class,调用指定的实现类. * @param string $flag * @param string $payType */ public static function factory($flag) { $className = self::_convertUnderline($flag); $className = "App\\Repositories\\Service\\Payment\\{$className}"; if (class_exists($className)) { return $className::getInstance(); } else { return new ErrorPayment(); } } /** * 获取最后一次错误信息 * @return */ public function getLastError() { return $this->_lastError; } /** * @param array $data * @return string 成功时 返回支付链接、失败时返回空字符串 并给 lastError 赋值 */ abstract public function createPayLink($data = array()); /** * @param string $orderSn 我方订单号 * @param string $tradeNo 支付方单号 * @param float $money 支付金额 * @param string $partnerId 商户号 * @return bool */ abstract public function notify(&$orderSn, &$tradeNo, &$money); /** * 发起http get 请求 * @param $url * @return string */ protected function httpGet($url) { $options = array( 'timeout' => 20, // 超时,单位秒. 'verify' => false, // 是否校验SSL证书. 'http_errors' => false, // 如果跟随http异常头部是否中断. 'debug' => false, // 是否启用调试模式. 'allow_redirects' => true, // 不跟随301/302跳转. ); $client = make(ClientFactory::class)->create($options); try { $result = $client->get($url); $code = $result->getStatusCode(); if ($code == 200) { return $result->getBody()->getContents(); } } catch (\Exception $e) { } return ''; } /** * 发起 http post 请求 * @param $url * @param $data * @return string */ protected function httpPost($url, $data) { $options = array( 'timeout' => 20, // 超时,单位秒. 'verify' => false, // 是否校验SSL证书. 'http_errors' => false, // 如果跟随http异常头部是否中断. 'debug' => false, // 是否启用调试模式. 'allow_redirects' => true, // 不跟随301/302跳转. ); $client = make(ClientFactory::class)->create($options); try { $params = [ 'form_params'=>$data, ]; $result = $client->post($url, $params); $code = $result->getStatusCode(); if ($code == 200) { return $result->getBody()->getContents(); } else { logger('PaymentInterface-httpPost-code-error', ['code' => $code]); return $code; } } catch (\Exception $e) { logger('PaymentInterface-httpPost-error', ['msg' => $e->getMessage()]); return $e->getMessage(); } return ''; } /** * 发起 http post 请求 * @param $url * @param $data * @return string */ public function httpPostJson($url, $data) { $options = array( 'timeout' => 20, // 超时,单位秒. 'verify' => false, // 是否校验SSL证书. 'http_errors' => false, // 如果跟随http异常头部是否中断. 'debug' => false, // 是否启用调试模式. 'allow_redirects' => true, // 不跟随301/302跳转. ); $client = make(ClientFactory::class)->create($options); try { $params = [ 'headers' => [ 'Content-Type'=>'application/json', ], 'json'=>$data, ]; $result = $client->post($url, $params); $code = $result->getStatusCode(); if ($code == 200) { return $result->getBody()->getContents(); } } catch (\Exception $e) { } return ''; } private static function _convertUnderline($str) { $string = ''; $arr = explode('_', $str); foreach ($arr as $value) { $string .= ucfirst(strtolower($value)); } return $string . 'Payment'; } /** * 签名算法 * * @param $data * @return string */ public function getSign($data) { ksort($data); $md5str = ""; foreach ($data as $key => $val) { $md5str = $md5str . $key . "=" . $val . "&"; } return $md5str; } /** * 构建rsa私钥 * * @param $privateKey * @return false|OpenSSLAsymmetricKey */ public function setupPrvKeySign($privateKey) { $pem = chunk_split($privateKey, 64, "\n"); $pem = "-----BEGIN RSA PRIVATE KEY-----\n" . $pem . "-----END RSA PRIVATE KEY-----\n"; $key = openssl_pkey_get_private($pem); return $key; } /** * 构建rsa共钥 * * @param $publicKey * @return false|OpenSSLAsymmetricKey */ public function setupPubKey($publicKey) { $pem = chunk_split($publicKey, 64, "\n"); $pem = "-----BEGIN PUBLIC KEY-----\n" . $pem . "-----END PUBLIC KEY-----"; $key = openssl_pkey_get_public($pem); return $key; } }