Alipay.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. declare(strict_types=1);
  3. namespace Yansongda\Pay\Provider;
  4. use GuzzleHttp\Psr7\Response;
  5. use GuzzleHttp\Psr7\ServerRequest;
  6. use Psr\Http\Message\MessageInterface;
  7. use Psr\Http\Message\ResponseInterface;
  8. use Psr\Http\Message\ServerRequestInterface;
  9. use Yansongda\Artful\Artful;
  10. use Yansongda\Artful\Event;
  11. use Yansongda\Artful\Exception\ContainerException;
  12. use Yansongda\Artful\Exception\InvalidParamsException;
  13. use Yansongda\Artful\Exception\ServiceNotFoundException;
  14. use Yansongda\Artful\Plugin\ParserPlugin;
  15. use Yansongda\Artful\Rocket;
  16. use Yansongda\Pay\Contract\ProviderInterface;
  17. use Yansongda\Pay\Event\CallbackReceived;
  18. use Yansongda\Pay\Event\MethodCalled;
  19. use Yansongda\Pay\Pay;
  20. use Yansongda\Pay\Plugin\Alipay\V2\AddPayloadSignaturePlugin;
  21. use Yansongda\Pay\Plugin\Alipay\V2\AddRadarPlugin;
  22. use Yansongda\Pay\Plugin\Alipay\V2\AppCallbackPlugin;
  23. use Yansongda\Pay\Plugin\Alipay\V2\CallbackPlugin;
  24. use Yansongda\Pay\Plugin\Alipay\V2\FormatPayloadBizContentPlugin;
  25. use Yansongda\Pay\Plugin\Alipay\V2\ResponsePlugin;
  26. use Yansongda\Pay\Plugin\Alipay\V2\StartPlugin;
  27. use Yansongda\Pay\Plugin\Alipay\V2\VerifySignaturePlugin;
  28. use Yansongda\Supports\Collection;
  29. use Yansongda\Supports\Str;
  30. /**
  31. * @method ResponseInterface|Rocket app(array $order) APP 支付
  32. * @method Collection|Rocket pos(array $order) 刷卡支付(付款码,被扫码)
  33. * @method Collection|Rocket scan(array $order) 扫码支付(摄像头,主动扫)
  34. * @method Collection|Rocket transfer(array $order) 帐户转账
  35. * @method ResponseInterface|Rocket h5(array $order) 手机网站支付
  36. * @method ResponseInterface|Rocket web(array $order) 电脑支付
  37. * @method Collection|Rocket mini(array $order) 小程序支付
  38. */
  39. class Alipay implements ProviderInterface
  40. {
  41. public const URL = [
  42. Pay::MODE_NORMAL => 'https://openapi.alipay.com/gateway.do?charset=utf-8',
  43. Pay::MODE_SANDBOX => 'https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8',
  44. Pay::MODE_SERVICE => 'https://openapi.alipay.com/gateway.do?charset=utf-8',
  45. ];
  46. /**
  47. * @throws ContainerException
  48. * @throws InvalidParamsException
  49. * @throws ServiceNotFoundException
  50. */
  51. public function __call(string $shortcut, array $params): null|Collection|MessageInterface|Rocket
  52. {
  53. $plugin = '\Yansongda\Pay\Shortcut\Alipay\\'.Str::studly($shortcut).'Shortcut';
  54. return Artful::shortcut($plugin, ...$params);
  55. }
  56. /**
  57. * @throws ContainerException
  58. * @throws InvalidParamsException
  59. */
  60. public function pay(array $plugins, array $params): null|Collection|MessageInterface|Rocket
  61. {
  62. return Artful::artful($plugins, $params);
  63. }
  64. /**
  65. * @throws ContainerException
  66. * @throws InvalidParamsException
  67. * @throws ServiceNotFoundException
  68. */
  69. public function query(array $order): Collection|Rocket
  70. {
  71. Event::dispatch(new MethodCalled('alipay', __METHOD__, $order, null));
  72. return $this->__call('query', [$order]);
  73. }
  74. /**
  75. * @throws ContainerException
  76. * @throws InvalidParamsException
  77. * @throws ServiceNotFoundException
  78. */
  79. public function cancel(array $order): Collection|Rocket
  80. {
  81. Event::dispatch(new MethodCalled('alipay', __METHOD__, $order, null));
  82. return $this->__call('cancel', [$order]);
  83. }
  84. /**
  85. * @throws ContainerException
  86. * @throws InvalidParamsException
  87. * @throws ServiceNotFoundException
  88. */
  89. public function close(array $order): Collection|Rocket
  90. {
  91. Event::dispatch(new MethodCalled('alipay', __METHOD__, $order, null));
  92. return $this->__call('close', [$order]);
  93. }
  94. /**
  95. * @throws ContainerException
  96. * @throws InvalidParamsException
  97. * @throws ServiceNotFoundException
  98. */
  99. public function refund(array $order): Collection|Rocket
  100. {
  101. Event::dispatch(new MethodCalled('alipay', __METHOD__, $order, null));
  102. return $this->__call('refund', [$order]);
  103. }
  104. /**
  105. * @throws ContainerException
  106. * @throws InvalidParamsException
  107. */
  108. public function callback(null|array|ServerRequestInterface $contents = null, ?array $params = null): Collection
  109. {
  110. $request = $this->getCallbackParams($contents);
  111. Event::dispatch(new CallbackReceived('alipay', $request->all(), $params, null));
  112. return $this->pay([CallbackPlugin::class], $request->merge($params)->all());
  113. }
  114. /**
  115. * @throws ContainerException
  116. * @throws InvalidParamsException
  117. */
  118. public function appCallback(null|array|ServerRequestInterface $contents = null, ?array $params = null): Collection
  119. {
  120. $request = $this->getCallbackParams($contents);
  121. return $this->pay([AppCallbackPlugin::class], $request->merge($params)->all());
  122. }
  123. public function success(): ResponseInterface
  124. {
  125. return new Response(200, [], 'success');
  126. }
  127. public function mergeCommonPlugins(array $plugins): array
  128. {
  129. return array_merge(
  130. [StartPlugin::class],
  131. $plugins,
  132. [FormatPayloadBizContentPlugin::class, AddPayloadSignaturePlugin::class, AddRadarPlugin::class, VerifySignaturePlugin::class, ResponsePlugin::class, ParserPlugin::class],
  133. );
  134. }
  135. protected function getCallbackParams(null|array|ServerRequestInterface $contents = null): Collection
  136. {
  137. if (is_array($contents)) {
  138. return Collection::wrap($contents);
  139. }
  140. if ($contents instanceof ServerRequestInterface) {
  141. return Collection::wrap('GET' === $contents->getMethod() ? $contents->getQueryParams()
  142. : $contents->getParsedBody());
  143. }
  144. $request = ServerRequest::fromGlobals();
  145. return Collection::wrap(
  146. array_merge($request->getQueryParams(), $request->getParsedBody())
  147. );
  148. }
  149. }