PayService.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. namespace addons\YunfastPay\common\services;
  3. use addons\YunfastPay\common\enums\YunfastPayTypeEnum;
  4. use addons\YunfastPay\common\models\PaymentOrder;
  5. use addons\YunfastPay\common\services\pays\cashier\ScanByAliPay;
  6. use addons\YunfastPay\common\services\pays\cashier\ScanByMiniProgramPay;
  7. use addons\YunfastPay\common\services\pays\cashier\ScanByWechatPay;
  8. use addons\YunfastPay\common\services\pays\order\AppPay;
  9. use addons\YunfastPay\common\services\pays\order\H5Pay;
  10. use addons\YunfastPay\common\services\pays\order\MiniProgramPay;
  11. use addons\YunfastPay\common\services\pays\order\WechatPay;
  12. use addons\YunfastPay\common\services\pays\PayInterface;
  13. use addons\YunfastPay\common\services\trans\TransAbstract;
  14. use common\models\common\PaymentTrade;
  15. use Yii;
  16. /**
  17. * 支付
  18. * @package addons\YunfastPay\common\services
  19. */
  20. class PayService extends BaseService
  21. {
  22. /**
  23. * @var TransAbstract
  24. */
  25. protected $trans;
  26. /**
  27. * @var string
  28. */
  29. protected $tradeType;
  30. /**
  31. * @var PaymentTrade
  32. */
  33. protected $trade;
  34. /**
  35. * @var YunPayService
  36. */
  37. protected $yunPay;
  38. /**
  39. * @var array
  40. */
  41. protected $result;
  42. /**
  43. * @var string
  44. */
  45. protected $openid;
  46. /**
  47. * @var array
  48. */
  49. protected $orders;
  50. /**
  51. * @var PayInterface
  52. */
  53. protected $pay;
  54. /**
  55. * @var integer
  56. */
  57. protected $storeId = 0;
  58. /**
  59. * @var array
  60. */
  61. protected $map = [
  62. YunfastPayTypeEnum::ALIPAY_APP => [
  63. 'class' => AppPay::class,
  64. ],
  65. YunfastPayTypeEnum::WEIXIN_H5 => [
  66. 'class' => H5Pay::class,
  67. ],
  68. YunfastPayTypeEnum::WEIXIN_GZH => [
  69. 'class' => WechatPay::class,
  70. ],
  71. YunfastPayTypeEnum::WEIXIN_XCX => [
  72. 'class' => MiniProgramPay::class,
  73. ],
  74. YunfastPayTypeEnum::ALIPAY_SCAN => [
  75. 'class' => ScanByAliPay::class,
  76. ],
  77. YunfastPayTypeEnum::WEIXIN_SCAN => [
  78. 'class' => ScanByWechatPay::class,
  79. ],
  80. YunfastPayTypeEnum::W_MINI_PROGRAM_SCAN => [
  81. 'class' => ScanByMiniProgramPay::class,
  82. ],
  83. ];
  84. protected function setParams(array $params)
  85. {
  86. $this->tradeType = $params['trade_type'];
  87. $this->trade = $params['trade'];
  88. }
  89. /**
  90. * 订单支付
  91. *
  92. * @param array $params
  93. * @return void
  94. */
  95. public function orderPay(
  96. PaymentTrade $trade,
  97. string $trade_type,
  98. string $openid
  99. )
  100. {
  101. $this->trade = $trade;
  102. $this->tradeType = $trade_type;
  103. $this->openid = $openid;
  104. $this->yunPay = new YunPayService(['mall_id' => $this->mall_id]);
  105. // $method = $this->getMethodByTradeType();
  106. // if (is_null($method)) throw new \Exception('未找到对应支付方式');
  107. $this->setTrans();
  108. // $this->setSplitBill();
  109. $this->sendPayRq();
  110. $this->addPayLog();
  111. return $this->getResult();
  112. }
  113. /**
  114. * 获取返回数据
  115. *
  116. * @return array
  117. */
  118. public function getResult()
  119. {
  120. return $this->result;
  121. }
  122. /**
  123. * @return PaymentTrade
  124. */
  125. public function getTrade()
  126. {
  127. return $this->trade;
  128. }
  129. /**
  130. * @return YunPayService
  131. */
  132. public function getYunPay()
  133. {
  134. return $this->yunPay;
  135. }
  136. /**
  137. * @return string
  138. */
  139. public function getOpenid()
  140. {
  141. return $this->openid;
  142. }
  143. /**
  144. * @return TransAbstract|null
  145. */
  146. protected function getClassByTradeType()
  147. {
  148. return !empty($this->map[$this->tradeType])
  149. ? $this->map[$this->tradeType]['class']
  150. : null;
  151. }
  152. /**
  153. * @return string|null
  154. */
  155. protected function getMethodByTradeType()
  156. {
  157. return !empty($this->map[$this->tradeType])
  158. ? $this->map[$this->tradeType]['method']
  159. : null;
  160. }
  161. /**
  162. * 设置支付trans
  163. *
  164. * @return void
  165. */
  166. protected function setTrans()
  167. {
  168. /**
  169. * @var PayInterface
  170. */
  171. $class = $this->getClassByTradeType();
  172. if (is_null($class)) throw new \Exception('未找到对应支付方式');
  173. /**
  174. * @var PayInterface
  175. */
  176. $this->pay = new $class($this);
  177. $this->trans = $this->pay->getTrans();
  178. }
  179. /**
  180. * 设置门店ID
  181. *
  182. * @return void
  183. */
  184. public function setStoreId(int $storeId)
  185. {
  186. $this->storeId = $storeId;
  187. }
  188. /**
  189. * 发送请求
  190. *
  191. * @return void
  192. */
  193. protected function sendPayRq()
  194. {
  195. $this->yunPay->setStoreId($this->storeId);
  196. $result = $this->yunPay->sendPayRq($this->trans);
  197. $this->result = $result;
  198. }
  199. /**
  200. * 设置分账
  201. *
  202. * @return void
  203. */
  204. protected function setSplitBill()
  205. {
  206. // 获取订单
  207. // $this->orders = PaymentTradeOrder::getStoreInfoByTradeId($this->trade->id);
  208. // 设置分账
  209. // $this->yunPay->setSplitBill($this->orders, $this->trans);
  210. }
  211. /**
  212. * 添加支付日志
  213. *
  214. * @return void
  215. */
  216. protected function addPayLog()
  217. {
  218. // 支付请求数据
  219. $reqData = $this->yunPay->getReqData();
  220. PaymentOrder::addLog([
  221. 'mall_id' => $this->mall_id,
  222. 'user_id' => $this->trade->user_id,
  223. 'trade_id' => $this->trade->id,
  224. 'amount' => $this->trade->pay_fee,
  225. 'order_no' => $reqData['outOrderId'],
  226. 'req_data' => $reqData,
  227. 'res_data' => $this->result,
  228. 'status' => !empty($this->result['transStatus']) ? $this->result['transStatus'] : '0',
  229. ]);
  230. }
  231. /**
  232. * 获取
  233. *
  234. * @return array
  235. */
  236. public function getPayData()
  237. {
  238. return $this->pay->getPayData(
  239. $this->getResult()
  240. );
  241. }
  242. /**
  243. * 支付回调处理
  244. *
  245. * @param array $respData
  246. * @return boolean
  247. */
  248. public function notify(array $respData)
  249. {
  250. /**
  251. * @var PaymentOrder
  252. */
  253. $order = PaymentOrder::getOrderByNo($this->mall_id, $respData['outOrderId']);
  254. if ($order->status == '100') return true;
  255. if ('100' == $respData['transStatus']) {
  256. // 对比金额
  257. if (bccomp($order->trade->pay_fee, $respData['transAmt'], 2) == 0) {
  258. $order->success($respData['orderCd']);
  259. return true;
  260. }
  261. } else if ('102' == $respData['transStatus']) {
  262. // 交易失败
  263. $order->fail();
  264. return $this->error('交易失败');
  265. } else {
  266. // 未知结果,这种情况不会有。
  267. return $this->error('未知情况');
  268. }
  269. }
  270. }