PayService.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace addons\Sicpay\common\services;
  3. use addons\Sicpay\common\models\SicpayConfig;
  4. use addons\Sicpay\common\models\SicpayConfig as Config;
  5. use addons\Sicpay\common\models\SicpayOrder;
  6. use addons\Sicpay\common\sdk\config\AlipayAppStruct;
  7. use addons\Sicpay\common\sdk\config\AlipayWapStruct;
  8. use addons\Sicpay\common\sdk\config\BaseStruct;
  9. use addons\Sicpay\common\sdk\config\CloudAppStruct;
  10. use addons\Sicpay\common\sdk\config\CloudH5Struct;
  11. use addons\Sicpay\common\sdk\config\QueryStruct;
  12. use addons\Sicpay\common\sdk\config\WechatAppStruct;
  13. use addons\Sicpay\common\sdk\config\WechatGZHStruct;
  14. use addons\Sicpay\common\sdk\config\WechatWapStruct;
  15. use addons\Sicpay\common\sdk\PayCore;
  16. use addons\Sicpay\common\sdk\PaySign;
  17. use common\models\common\PaymentTrade;
  18. use common\models\common\PaymentTradeOrder;
  19. use common\models\common\PaymentTradeGroupOrder;
  20. class PayService extends BaseService
  21. {
  22. // 查询是否支付成功
  23. public function query($order_no){
  24. $order = SicpayOrder::findOne(['order_no'=>$order_no]);
  25. if(empty($order)){
  26. return $this->error("订单不存在");
  27. }
  28. $struct = new QueryStruct(['mall_id'=>$order->mall_id,'order_no'=>$order->order_no]);
  29. $resp = $struct->query();
  30. if($resp === false) return $this->error($struct->error);
  31. // 支付处理
  32. return $this->_handel_order($order->id,$resp);
  33. }
  34. // 下单
  35. public function create(PaymentTrade $trade,$trade_type){
  36. $config = Config::getConfig($trade->mall_id);
  37. $trade_type = trim($trade_type);
  38. // 增加组合支付判断
  39. if(!empty($trade->is_pay_group)){
  40. $paymentOrderObj = PaymentTradeGroupOrder::class;
  41. }else{
  42. $paymentOrderObj = PaymentTradeOrder::class;
  43. }
  44. $mall_order_no = $paymentOrderObj::find()->where(['trade_id'=>$trade->id])->select("order_no")->column();
  45. // 支付方式
  46. $order = [
  47. "mall_id"=>$trade->mall_id,
  48. "order_no"=>$trade->out_trade_no,
  49. "mall_order_no"=>$mall_order_no[0] ?? '',
  50. "type"=>$trade_type,
  51. "agencyId"=>$config->agencyId,
  52. "amount"=>$trade->pay_fee,
  53. "product_name"=>$trade->title,
  54. "created_at"=>time(),
  55. "updated_at"=>time(),
  56. ];
  57. switch ($trade_type){
  58. case Config::CLOUD_H5:
  59. // 银联在线
  60. $struct = new CloudH5Struct($order);
  61. break;
  62. case Config::CLOUD_APP:
  63. // 云闪付
  64. $struct = new CloudAppStruct($order);
  65. break;
  66. case Config::ALIPAY_APP:
  67. // 支付宝app支付
  68. $struct = new AlipayAppStruct($order);
  69. break;
  70. case Config::WECHAT_APP:
  71. // 微信app支付
  72. $struct = new WechatAppStruct($order);
  73. break;
  74. case Config::WECHAT_GZH:
  75. // 微信公众号支付
  76. $struct = new WechatGZHStruct($order);
  77. break;
  78. case Config::WECHAT_WAP:
  79. // 微信h5支付
  80. $struct = new WechatWapStruct($order);
  81. break;
  82. case Config::ALIPAY_WAP:
  83. // 支付宝wap支付(手机网页、电脑网页)
  84. $struct = new AlipayWapStruct($order);
  85. break;
  86. default:
  87. throw new \Exception("SICPAY 不支持 {$trade_type} 交易");
  88. }
  89. $model = new SicpayOrder();
  90. if(!($model->load($order,'') && $model->save())){
  91. $msg = array_values($model->getErrors())[0] ?? "SICPAY 未知错误";
  92. return $this->error($msg);
  93. }
  94. // 请求接口
  95. $res = $struct->pay();
  96. if($res == false){
  97. throw new \Exception($struct->error);
  98. }
  99. // 返回数据
  100. $resp = $struct->returnData();
  101. if(!empty($resp['form'])){
  102. // 有返回form表单的话,缓存起来,
  103. $url = "sicpay:order:{$struct->mall_id}:".$struct->order_no;
  104. \Yii::$app->redis->setex($url,1800,$resp['form']);
  105. $resp['url'] = \Yii::$app->services->setting->platform->get('system.api_url')."/sicpay/notify/topay?order_no=$url";
  106. unset($resp['form']);
  107. }
  108. $resp['trade_type'] = $trade_type;
  109. // 更新记录
  110. $model->pay_no = $resp['pay_no'];
  111. $model->token_id = $resp['token_id'] ?? '';
  112. $model->response_json = $resp['form'] ?? '';
  113. $model->request_json = json_encode($struct->getConfig());
  114. $model->save();
  115. return $resp;
  116. }
  117. // 支付异步回调
  118. public function notifyHandle($mall_id,$data){
  119. $config = SicpayConfig::getConfig($mall_id);
  120. $core = new PaySign();
  121. $pay_data = $core->notifyDecodeData($config,$data);
  122. $order = SicpayOrder::findOne(['order_no'=>$pay_data['order_no'] ?? '']);
  123. if(empty($order)){
  124. return false;
  125. }
  126. list($res,$pay_status) = $this->_handel_order($order->id,$pay_data);
  127. if($res && $pay_status == 1){
  128. // 支付成功
  129. return [
  130. 'out_trade_no'=>$order->order_no,
  131. 'pay_fee'=>$order->amount,
  132. ];
  133. }
  134. return false;
  135. }
  136. private function _handel_order($order_id,$resp){
  137. $is_ok = $resp['pay_result'];
  138. $res = false;
  139. if($resp['pay_result'] == 1){
  140. // 成功
  141. $res = SicpayOrder::pay_success($order_id,$resp['pay_no'],$resp['pay_time'],$resp);
  142. }else if($resp['pay_result'] == 0){
  143. // 未支付,不处理
  144. }else if($resp['pay_result'] == 2){
  145. // 支付失败
  146. $res = SicpayOrder::pay_fail($order_id,$resp['err_msg'],$resp);
  147. }else if($resp['pay_result'] == 6){
  148. // 已关闭
  149. $res = SicpayOrder::pay_close($order_id,$resp['err_msg'],$resp);
  150. }
  151. return [$res,$is_ok];
  152. }
  153. }