/** * 生成用于回复的数据 * * @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())); }
/** * 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()); }
/** * 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); }
/** * 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; }
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; }
/** * 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; }
/** * 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); }
/** * 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()); }
/** * 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)); }
/** * 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; }
/** * Parse Response XML to array. * * @param string $response * * @return Collection */ protected function parseResponse($response) { return new Collection((array) XML::parse($response)); }
/** * 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)); }
/** * 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; }
/** * 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)); }
/** * 检验消息的真实性,并且获取解密后的明文. * <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)); }
/** * 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))); }
/** * 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())); }
/** * Parse Response XML to array. * * @param string $response * * @return array */ protected function parseResponse($response) { return XML::parse($response); }
/** * 初始化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)); }