Пример #1
0
 /**
  * 生成用于回复的数据
  *
  * @return array
  */
 public function buildForReply()
 {
     if (!method_exists($this, 'toReply')) {
         throw new Exception(__CLASS__ . '未实现此方法:toReply()');
     }
     $base = array('ToUserName' => $this->to, 'FromUserName' => $this->from, 'CreateTime' => time(), 'MsgType' => $this->getDefaultMessageType());
     return XML::build(array_merge($base, $this->toReply()));
 }
Пример #2
0
 /**
  * Test isInvalid().
  */
 public function testIsValid()
 {
     $params = ['foo' => 'bar', 'hi' => 'here'];
     $params['sign'] = \EasyWeChat\Payment\generate_sign($params, 'sign_key');
     $request = Request::create('/callback', 'POST', [], [], [], [], XML::build($params));
     $notify = new Notify(new Merchant(['key' => 'sign_key']), $request);
     $this->assertTrue($notify->isValid());
     $notify = new Notify(new Merchant(['key' => 'different_sign_key']), $request);
     $this->assertFalse($notify->isValid());
 }
Пример #3
0
 /**
  * Build input.
  *
  * @param Cryptor $cryptor
  *
  * @return array
  */
 protected function build($cryptor)
 {
     $xml = file_get_contents('php://input');
     $input = XML::parse($xml);
     if (empty($_REQUEST['echostr']) && !empty($_REQUEST['encrypt_type']) && $_REQUEST['encrypt_type'] === 'aes') {
         $this->encrypted = true;
         $input = $cryptor->decryptMsg($_REQUEST['msg_signature'], $_REQUEST['nonce'], $_REQUEST['timestamp'], $xml);
     }
     /* @var array $input */
     return array_merge($_REQUEST, (array) $input);
 }
Пример #4
0
 /**
  * Build API instance.
  *
  * @return API
  */
 public function getAPI()
 {
     $http = Mockery::mock(Http::class);
     $http->shouldReceive('request')->andReturnUsing(function ($api, $method, $options) {
         $options['body'] = XML::parse($options['body']);
         return XML::build(compact('api', 'options'));
     });
     $merchant = new Merchant(['merchant_id' => 'testMerchantId', 'app_id' => 'wxTestAppId', 'key' => 'testKey', 'cert_path' => 'testCertPath', 'key_path' => 'testKeyPath']);
     $api = Mockery::mock('EasyWeChat\\Payment\\LuckyMoney\\API[getHttp]', [$merchant]);
     $api->shouldReceive('getHttp')->andReturn($http);
     return $api;
 }
Пример #5
0
 public function getServer($message = '', $queries = null)
 {
     $request = Mockery::mock(Request::class . '[get,getContent]');
     $request->shouldReceive('get')->andReturnUsing(function ($key) use($queries) {
         $queries = $queries ?: ['signature' => '5fe39987c51aa87c0da1af7420d4649d77850391', 'timestamp' => '1437865042', 'nonce' => '335941714'];
         return isset($queries[$key]) ? $queries[$key] : null;
     });
     $message = $message ?: ['ToUserName' => 'gh_9a1a7e312b32', 'FromUserName' => 'oNlnUjq_uJdd52zt3OxFsJHEr_NY', 'CreateTime' => '1437865042', 'MsgType' => 'text', 'Content' => 'foobar', 'MsgId' => '6175583331658476609'];
     $request->shouldReceive('getContent')->andReturn(XML::build($message));
     $server = new Guard($request);
     return $server;
 }
Пример #6
0
 /**
  * Build API instance.
  *
  * @return API
  */
 public function getAPI()
 {
     $http = Mockery::mock(Http::class);
     $http->shouldReceive('post')->andReturnUsing(function ($api, $params) {
         $params = XML::parse($params);
         return XML::build(compact('api', 'params'));
     });
     $merchant = new Merchant(['fee_type' => 'CNY', 'merchant_id' => 'testMerchantId', 'app_id' => 'wxTestAppId', 'device_info' => 'testDeviceInfo', 'key' => 'testKey']);
     $api = Mockery::mock('EasyWeChat\\Payment\\API[getHttp]', [$merchant]);
     $api->shouldReceive('getHttp')->andReturn($http);
     return $api;
 }
Пример #7
0
 /**
  * Return the notify body from request.
  *
  * @return \EasyWeChat\Support\Collection
  */
 public function getNotify()
 {
     if (!empty($this->notify)) {
         return $this->notify;
     }
     try {
         $xml = XML::parse(strval($this->request->getContent()));
     } catch (\Throwable $t) {
         throw new FaultException('Invalid request XML: ' . $t->getMessage(), 400);
     } catch (\Exception $e) {
         throw new FaultException('Invalid request XML: ' . $e->getMessage(), 400);
     }
     if (!is_array($xml) || empty($xml)) {
         throw new FaultException('Invalid request XML.', 400);
     }
     return $this->notify = new Collection($xml);
 }
Пример #8
0
 /**
  * Test handleNotify().
  */
 public function testHandleNotify()
 {
     $merchant = new Merchant(['key' => 'different_sign_key']);
     $payment = Mockery::mock(Payment::class . '[getNotify]', [$merchant]);
     $request = Request::create('/callback', 'POST', [], [], [], [], '<xml><foo>bar</foo></xml>');
     $notify = Mockery::mock(Notify::class . '[isValid]', [$merchant, $request]);
     $notify->shouldReceive('isValid')->andReturn(true);
     $payment->shouldReceive('getNotify')->andReturn($notify);
     $response = $payment->handleNotify(function () {
         return true;
     });
     $this->assertInstanceOf(Response::class, $response);
     $this->assertEquals(XML::build(['return_code' => 'SUCCESS', 'return_msg' => 'OK']), $response->getContent());
     $response = $payment->handleNotify(function () {
         return 'error_message';
     });
     $this->assertEquals(XML::build(['return_code' => 'FAIL', 'return_msg' => 'error_message']), $response->getContent());
     $response = $payment->handleNotify(function () {
         return false;
     });
     $this->assertEquals(XML::build(['return_code' => 'FAIL', 'return_msg' => '']), $response->getContent());
 }
Пример #9
0
 /**
  * Decrypt message.
  *
  * @param string $msgSignature
  * @param string $nonce
  * @param string $timestamp
  * @param string $postXML
  *
  * @return array
  *
  * @throws Exception
  */
 public function decryptMsg($msgSignature, $nonce, $timestamp, $postXML)
 {
     try {
         $array = XML::parse($postXML);
     } catch (BaseException $e) {
         throw new Exception('Invalid xml.', Exception::ERROR_PARSE_XML);
     }
     $encrypted = $array['Encrypt'];
     $signature = $this->getSHA1($this->token, $timestamp, $nonce, $encrypted);
     if ($signature !== $msgSignature) {
         throw new Exception('Invalid Signature.', Exception::ERROR_INVALID_SIGNATURE);
     }
     return XML::parse($this->decrypt($encrypted, $this->appId));
 }
Пример #10
0
 /**
  * Parse message array from raw php input.
  *
  * @param string|resource $content
  *
  * @throws \EasyWeChat\Core\Exceptions\RuntimeException
  * @throws \EasyWeChat\Encryption\EncryptionException
  *
  * @return array
  */
 protected function parseMessageFromRequest($content)
 {
     $content = strval($content);
     if ($this->isSafeMode()) {
         if (!$this->encryptor) {
             throw new RuntimeException('Safe mode Encryptor is necessary, please use Guard::setEncryptor(Encryptor $encryptor) set the encryptor instance.');
         }
         $message = $this->encryptor->decryptMsg($this->request->get('msg_signature'), $this->request->get('nonce'), $this->request->get('timestamp'), $content);
     } else {
         $message = XML::parse($content);
     }
     return $message;
 }
Пример #11
0
 /**
  * Parse Response XML to array.
  *
  * @param string $response
  *
  * @return Collection
  */
 protected function parseResponse($response)
 {
     return new Collection((array) XML::parse($response));
 }
Пример #12
0
 /**
  * Handle payment notify.
  *
  * @param callable $callback
  *
  * @return Response
  */
 public function handleNotify(callable $callback)
 {
     $notify = $this->getNotify();
     if (!$notify->isValid()) {
         throw new FaultException('Invalid request XML.', 400);
     }
     $notify = $notify->getNotify();
     $successful = $notify->get('result_code') === 'SUCCESS';
     $handleResult = call_user_func_array($callback, [$notify, $successful]);
     if (is_bool($handleResult) && $handleResult) {
         $response = ['return_code' => 'SUCCESS', 'return_msg' => 'OK'];
     } else {
         $response = ['return_code' => 'FAIL', 'return_msg' => $handleResult];
     }
     return new Response(XML::build($response));
 }
Пример #13
0
 /**
  * Parse message array from raw php input.
  *
  * @param string $content
  *
  * @throws \EasyWeChat\Core\Exceptions\RuntimeException
  * @throws \EasyWeChat\Encryption\EncryptionException
  *
  * @return array
  */
 protected function parseMessageFromRequest($content)
 {
     if ($this->isSafeMode()) {
         if (!$this->encryptor) {
             throw new RuntimeException('Safe mode Encryptor is necessary.');
         }
         $message = $this->encryptor->decryptMsg($this->request->get('msg_signature'), $this->request->get('nonce'), $this->request->get('timestamp'), $content);
     } else {
         $message = XML::parse($content);
     }
     return $message;
 }
Пример #14
0
 /**
  * Parse Response XML to array.
  *
  * @param ResponseInterface $response
  *
  * @return \EasyWeChat\Support\Collection
  */
 protected function parseResponse($response)
 {
     if ($response instanceof ResponseInterface) {
         $response = $response->getBody();
     }
     return new Collection((array) XML::parse($response));
 }
Пример #15
0
 /**
  * 检验消息的真实性,并且获取解密后的明文.
  * <ol>
  *    <li>利用收到的密文生成安全签名,进行签名验证</li>
  *    <li>若验证通过,则提取xml中的加密消息</li>
  *    <li>对消息进行解密</li>
  * </ol>
  *
  * @param string $msgSignature 签名串,对应URL参数的msg_signature
  * @param string $nonce        随机串,对应URL参数的nonce
  * @param string $timestamp    时间戳 对应URL参数的timestamp
  * @param string $postXML      密文,对应POST请求的数据
  *
  * @return array
  */
 public function decryptMsg($msgSignature, $nonce, $timestamp, $postXML)
 {
     //提取密文
     $array = XML::parse($postXML);
     if (empty($array)) {
         throw new Exception('Invalid xml.', self::ERROR_PARSE_XML);
     }
     $encrypted = $array['Encrypt'];
     //验证安全签名
     $signature = $this->getSHA1($this->token, $timestamp, $nonce, $encrypted);
     if ($signature !== $msgSignature) {
         throw new Exception('Invalid Signature.', self::ERROR_INVALID_SIGNATURE);
     }
     return XML::parse($this->decrypt($encrypted, $this->appId));
 }
Пример #16
0
 /**
  * Build reply XML.
  *
  * @param string           $to
  * @param string           $from
  * @param MessageInterface $message
  *
  * @return string
  */
 protected function buildReply($to, $from, $message)
 {
     $base = ['ToUserName' => $to, 'FromUserName' => $from, 'CreateTime' => time(), 'MsgType' => $message->getType()];
     return XML::build(array_merge($base, $this->transformer->transform($message)));
 }
Пример #17
0
 /**
  * Build message for reply.
  *
  * @return array
  */
 public function buildForReply()
 {
     $base = array('ToUserName' => $this->to, 'FromUserName' => $this->from, 'CreateTime' => time(), 'MsgType' => $this->getDefaultMessageType());
     return XML::build(array_merge($base, $this->toReply()));
 }
Пример #18
0
 /**
  * Parse Response XML to array.
  *
  * @param string $response
  *
  * @return array
  */
 protected function parseResponse($response)
 {
     return XML::parse($response);
 }
Пример #19
0
 /**
  * 初始化POST请求数据
  *
  * @return Collection
  */
 protected function prepareInput()
 {
     if ($this->input instanceof Collection) {
         return;
     }
     if (!empty($GLOBALS['HTTP_RAW_POST_DATA'])) {
         $xmlInput = $GLOBALS['HTTP_RAW_POST_DATA'];
     } else {
         $xmlInput = file_get_contents('php://input');
     }
     $input = XML::parse($xmlInput);
     if (!empty($_REQUEST['encrypt_type']) && $_REQUEST['encrypt_type'] === 'aes') {
         $this->security = true;
         $input = $this->getCrypt()->decryptMsg($_REQUEST['msg_signature'], $_REQUEST['nonce'], $_REQUEST['timestamp'], $xmlInput);
     }
     $this->input = new Collection(array_merge($_REQUEST, (array) $input));
 }