WechatPay.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. namespace common\components\payment;
  3. use yii\helpers\Json;
  4. use yii\web\UnprocessableEntityHttpException;
  5. use common\helpers\ArrayHelper;
  6. use Yansongda\Pay\Pay;
  7. use Yansongda\Pay\Exception\InvalidResponseException;
  8. use Yansongda\Pay\Contract\ConfigInterface;
  9. use Yansongda\Pay\Exception\InvalidConfigException;
  10. use Yansongda\Pay\Plugin\ParserPlugin;
  11. use Yansongda\Pay\Plugin\Wechat\PreparePlugin;
  12. use Yansongda\Pay\Plugin\Wechat\SignPlugin;
  13. use Yansongda\Pay\Plugin\Wechat\WechatPublicCertsPlugin;
  14. /**
  15. * 微信支付类
  16. *
  17. * Class WechatPay
  18. * @package common\components\payment
  19. */
  20. class WechatPay
  21. {
  22. protected $config;
  23. /**
  24. * WechatPay constructor.
  25. */
  26. public function __construct($config)
  27. {
  28. // 初始化
  29. Pay::config($config);
  30. $this->config = $config;
  31. }
  32. /**
  33. * @return array
  34. * @throws InvalidConfigException
  35. * @throws InvalidResponseException
  36. * @throws \Yansongda\Pay\Exception\ContainerException
  37. * @throws \Yansongda\Pay\Exception\InvalidParamsException
  38. * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
  39. */
  40. public function getPublicCerts()
  41. {
  42. $params = $this->config['wechat']['default'];
  43. $data = Pay::wechat()->pay(
  44. [PreparePlugin::class, WechatPublicCertsPlugin::class, SignPlugin::class, ParserPlugin::class],
  45. $params
  46. )->get('data', []);
  47. foreach ($data as $item) {
  48. $certs[$item['serial_no']] = decrypt_wechat_resource($item['encrypt_certificate'], $params)['ciphertext'] ?? '';
  49. }
  50. $wechatConfig = get_wechat_config($params);
  51. $wechatConfig['wechat_public_cert_path'] = ((array) $wechatConfig['wechat_public_cert_path']) + ($certs ?? []);
  52. Pay::set(ConfigInterface::class, Pay::get(ConfigInterface::class)->merge([
  53. 'wechat' => [$params['_config'] ?? 'default' => $wechatConfig->all()],
  54. ]));
  55. return $certs;
  56. }
  57. /**
  58. * @return \Yansongda\Supports\Collection
  59. * @throws \Yansongda\Pay\Exception\ContainerException
  60. * @throws \Yansongda\Pay\Exception\InvalidParamsException
  61. */
  62. public function callback()
  63. {
  64. return Pay::wechat()->callback();
  65. }
  66. /**
  67. * @return \Psr\Http\Message\ResponseInterface
  68. */
  69. public function success()
  70. {
  71. return Pay::wechat()->success();
  72. }
  73. /**
  74. * 微信APP支付网关
  75. *
  76. * @param $order
  77. * @return \Yansongda\Supports\Collection
  78. * @throws UnprocessableEntityHttpException
  79. */
  80. public function app($order)
  81. {
  82. try {
  83. $data = Pay::wechat()->app($order);
  84. } catch (InvalidResponseException $invalidResponseException) {
  85. $this->getError($invalidResponseException->extra);
  86. }
  87. return $data;
  88. }
  89. /**
  90. * 微信原生扫码支付支付网关
  91. *
  92. * @param array $order
  93. * @param bool $debug
  94. * @return mixed
  95. */
  96. public function scan($order)
  97. {
  98. try {
  99. $data = Pay::wechat()->scan($order);
  100. } catch (InvalidResponseException $invalidResponseException) {
  101. $this->getError($invalidResponseException->extra);
  102. }
  103. return $data;
  104. }
  105. /**
  106. * 微信公众号支付支付网关
  107. *
  108. * @param array $order
  109. * $order = [
  110. * 'out_trade_no' => time().'',
  111. * 'description' => 'subject-测试',
  112. * 'amount' => [
  113. * 'total' => 1,
  114. * ],
  115. * 'payer' => [
  116. * 'openid' => 'onkVf1FjWS5SBxxxxxxxx',
  117. * ],
  118. * ];
  119. * @param bool $debug
  120. * @return array
  121. */
  122. public function mp($order)
  123. {
  124. try {
  125. $data = Pay::wechat()->mp($order);
  126. } catch (InvalidResponseException $invalidResponseException) {
  127. $this->getError($invalidResponseException->extra);
  128. }
  129. $data = ArrayHelper::toArray($data);
  130. if (isset($data['timeStamp'])) {
  131. $data['timestamp'] = $data['timeStamp'];
  132. unset($data['timeStamp']);
  133. }
  134. return $data;
  135. }
  136. /**
  137. * 小程序支付
  138. *
  139. * @param $order
  140. * @param bool $debug
  141. * @return array|mixed|null
  142. */
  143. public function mini($order)
  144. {
  145. try {
  146. $data = Pay::wechat()->mini($order);
  147. } catch (InvalidResponseException $invalidResponseException) {
  148. $this->getError($invalidResponseException->extra);
  149. }
  150. $data = ArrayHelper::toArray($data);
  151. if (isset($data['timeStamp'])) {
  152. $data['timestamp'] = $data['timeStamp'];
  153. unset($data['timeStamp']);
  154. }
  155. return $data;
  156. }
  157. /**
  158. * 微信刷卡支付网关
  159. *
  160. * @param array $order
  161. * [
  162. * 'body' => 'The test order',
  163. * 'out_trade_no' => date('YmdHis') . mt_rand(1000, 9999),
  164. * 'total_fee' => 1, //=0.01,
  165. * 'auth_code' => '',
  166. * ]
  167. * @param bool $debug
  168. * @return mixed
  169. */
  170. public function pos($order)
  171. {
  172. }
  173. /**
  174. * 微信H5支付网关
  175. * @param array $order
  176. * $order = [
  177. * 'out_trade_no' => time().'',
  178. * 'description' => 'subject-测试',
  179. * 'amount' => [
  180. * 'total' => 1,
  181. * ],
  182. * 'scene_info' => [
  183. * 'payer_client_ip' => '1.2.4.8',
  184. * 'h5_info' => [
  185. * 'type' => 'Wap',
  186. * ]
  187. * ],
  188. * ];
  189. * @param bool $debug
  190. * @return mixed
  191. */
  192. public function wap($order)
  193. {
  194. try {
  195. $data = Pay::wechat()->wap($order);
  196. } catch (InvalidResponseException $invalidResponseException) {
  197. $this->getError($invalidResponseException->extra);
  198. }
  199. return ArrayHelper::toArray($data);
  200. }
  201. /**
  202. * 关闭订单
  203. *
  204. * $order = [
  205. * 'out_trade_no' => '1217752501201407033233368018',
  206. * ];
  207. *
  208. * or
  209. *
  210. * $order = '1217752501201407033233368018';
  211. */
  212. public function close($order)
  213. {
  214. Pay::wechat()->close($order);
  215. }
  216. /**
  217. * 转账
  218. *
  219. * @param $order
  220. * @return mixed
  221. */
  222. public function transfer($order)
  223. {
  224. /** @var $data */
  225. $result = Pay::wechat()->transfer($order);
  226. $data = ArrayHelper::toArray($result);
  227. if (isset($data['code'])) {
  228. throw new UnprocessableEntityHttpException($data['message']);
  229. }
  230. return $data;
  231. }
  232. /**
  233. * 查询订单
  234. *
  235. * $order = [
  236. * 'transaction_id' => '1217752501201407033233368018',
  237. * ];
  238. *
  239. * or
  240. *
  241. * $order = '1217752501201407033233368018';
  242. */
  243. public function find($order)
  244. {
  245. return Pay::wechat()->find($order);
  246. }
  247. /**
  248. * 查询退款订单
  249. *
  250. * @param $transaction_id
  251. */
  252. public function findRefund($transaction_id)
  253. {
  254. $order = [
  255. 'transaction_id' => $transaction_id,
  256. '_type' => 'refund',
  257. ];
  258. return Pay::wechat()->find($order);
  259. }
  260. /**
  261. * 退款
  262. *
  263. * 订单类型
  264. *
  265. * @param $order
  266. * $order = [
  267. * 'out_trade_no' => '1514192025',
  268. * 'out_refund_no' => time(),
  269. * 'amount' => [
  270. * 'refund' => 1,
  271. * 'total' => 1,
  272. * 'currency' => 'CNY',
  273. * ],
  274. * ];
  275. */
  276. public function refund($order)
  277. {
  278. return Pay::wechat()->refund($order);
  279. }
  280. /**
  281. * @param $error
  282. * @return mixed
  283. * @throws UnprocessableEntityHttpException
  284. */
  285. protected function getError($error)
  286. {
  287. if (is_array($error) && isset($error['code']) && isset($error['message'])) {
  288. throw new UnprocessableEntityHttpException($error['message']);
  289. }
  290. $extraBody = Json::decode($error['body']);
  291. throw new UnprocessableEntityHttpException($extraBody['message']);
  292. }
  293. }
粤ICP备19079148号