YopproController.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: blank
  5. * Date: 2020/2/11
  6. * Time: 14:53
  7. */
  8. namespace app\payment\controllers;
  9. use app\common\helpers\Url;
  10. use app\common\services\Pay;
  11. use app\common\services\PayFactory;
  12. use app\payment\PaymentController;
  13. use app\common\modules\yop\sdk\Util\YopSignUtils;
  14. use app\common\models\AccountWechats;
  15. use Illuminate\Support\Facades\DB;
  16. use Yunshop\YopPro\models\AccountDivided;
  17. use Yunshop\YopPro\models\AccountDividedLog;
  18. use Yunshop\YopPro\models\Merchant;
  19. use Yunshop\YopPro\models\YopProOrder;
  20. use Yunshop\YopPro\models\YopProOrderRefund;
  21. use Yunshop\YopPro\services\WithdrawService;
  22. class YopproController extends PaymentController
  23. {
  24. protected $set;
  25. protected $parameters;
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. if (!app('plugins')->isEnabled('yop-pro')) {
  30. echo 'Not turned on yop pro';
  31. exit();
  32. }
  33. $this->set = $this->getMerchantNo();
  34. if (empty(\YunShop::app()->uniacid)) {
  35. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = $this->set['uniacid'];
  36. AccountWechats::setConfig(AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid));
  37. }
  38. $this->init();
  39. }
  40. protected function getMerchantNo()
  41. {
  42. \Log::debug('--------------易宝入网参数--------------', $_REQUEST);
  43. $app_key = $_REQUEST['customerIdentification'];
  44. $merchant_no = substr($app_key, strrpos($app_key, 'OPR:')+4);
  45. $model = DB::table('yz_yop_pro_set')->where('parent_merchant_no', $merchant_no)->first();
  46. if (empty($model)) {exit('商户不存在');}
  47. return is_array($model)?$model:$model->toArray();
  48. }
  49. private function init()
  50. {
  51. $yop_data = $_REQUEST['response'];
  52. if ($yop_data) {
  53. $response = YopSignUtils::decrypt($yop_data, $this->set['parent_private_key'], $this->set['yop_public_key']);
  54. $this->parameters = json_decode($response, true);
  55. }
  56. }
  57. //子商户入网
  58. public function merNotifyUrl()
  59. {
  60. \Log::debug('子商户入网:'.$this->parameters['requestNo'], $this->parameters);
  61. $merchant = Merchant::where('requestNo', $this->parameters['requestNo'])->first();
  62. if (empty($merchant)) {
  63. exit('Merchant does not exist');
  64. }
  65. $status = $this->merNetInStatus();
  66. $merchant->status = $status;
  67. $merchant->remark = $this->parameters['remark'] ?: '';
  68. $bool = $merchant->save();
  69. if ($bool) {
  70. echo 'SUCCESS';exit();
  71. } else {
  72. echo '保存出错';exit();
  73. }
  74. }
  75. protected function merNetInStatus()
  76. {
  77. $status = Merchant::INVALID;
  78. if (!empty($this->parameters['merNetInStatus'])) {
  79. switch ($this->parameters['merNetInStatus']) {
  80. case 'PROCESS_SUCCESS': //审核通过
  81. $status = Merchant::PROCESS_SUCCESS;
  82. break;
  83. case 'PROCESS_REJECT': //审核拒绝
  84. $status = Merchant::PROCESS_REJECT;
  85. break;
  86. case 'PROCESS_BACK': //审核回退
  87. $status = Merchant::PROCESS_BACK;
  88. break;
  89. case 'PROCESSING_PRODUCT_INFO_SUCCESS': //审核中-产品提前开通
  90. $status = Merchant::PROCESSING_PRODUCT_INFO_SUCCESS;
  91. break;
  92. default:
  93. break;
  94. }
  95. }
  96. return $status;
  97. }
  98. //聚合报备
  99. public function backUrl()
  100. {
  101. \Log::debug('-------------聚合报备---------------', $this->parameters);
  102. $this->debug('聚合报备:'.$this->parameters['merchantNo'], $this->parameters);
  103. $merchant = Merchant::where('merchantNo', $this->parameters['merchantNo'])->first();
  104. if (empty($merchant)) {
  105. exit('Merchant does not exist');
  106. }
  107. $report_status = $this->reportStatusCode();
  108. $merchant->report_status = $report_status;
  109. $bool = $merchant->save();
  110. if ($bool) {
  111. echo 'SUCCESS';exit();
  112. } else {
  113. echo '保存出错';exit();
  114. }
  115. }
  116. protected function reportStatusCode()
  117. {
  118. switch ($this->getParameter('reportStatusCode')) {
  119. //报备成功
  120. case '':
  121. case 'NULL':
  122. case '0000':
  123. $report_status = Merchant::BACK_SUCCESS;
  124. break;
  125. //处理中
  126. case '1111':
  127. case '1112':
  128. case '3333':
  129. case '710001':
  130. $report_status = Merchant::BACK_WAIT;
  131. break;
  132. //失败
  133. default:
  134. $report_status = Merchant::BACK_FAIL;
  135. break;
  136. }
  137. return $report_status;
  138. }
  139. /**
  140. * 异步支付成功通知
  141. */
  142. public function notifyUrl()
  143. {
  144. $this->debug('-------支付------', $this->parameters);
  145. $this->log($this->getParameter('orderId'), $this->parameters);
  146. $this->savePayOrder();
  147. //$this->withdrawUpdate();
  148. $data = [
  149. 'total_fee' => floatval($this->getParameter('orderAmount')),
  150. 'out_trade_no' => $this->getParameter('orderId'),
  151. 'trade_no' => $this->getParameter('uniqueOrderNo'),
  152. 'unit' => 'yuan',
  153. 'pay_type' => '易宝Pro微信',
  154. 'pay_type_id' => PayFactory::YOP_PRO_WECHAT,
  155. ];
  156. //支付产品为用户扫码 支付类型为支付宝
  157. if ($this->paymentProduct() == YopProOrder::SCCANPAY && $this->platformType() == YopProOrder::TYPE_ALIPAY) {
  158. $data['pay_type'] = '易宝Pro支付宝';
  159. $data['pay_type_id'] = PayFactory::YOP_PRO_ALIPAY;
  160. }
  161. $this->payResutl($data);
  162. echo 'SUCCESS'; exit();
  163. }
  164. //同步通知
  165. public function redirectUrl()
  166. {
  167. //$url = str_replace('https','http', Url::shopSchemeUrl("?menu#/member/payYes?i={$uniacid}"));
  168. //redirect($url)->send();
  169. redirect(Url::absoluteApp('member/orderList/0', ['i' => \YunShop::app()->uniacid]))->send();
  170. }
  171. //订单超时通知地址
  172. public function timeoutNotifyUrl()
  173. {
  174. $this->debug('<-------易宝支付订单超时通知-------------->', $this->parameters);
  175. AccountDividedLog::where('pay_sn', $this->getParameter('orderId'))->delete();
  176. }
  177. /**
  178. * 修改分账记录状态
  179. */
  180. protected function withdrawUpdate()
  181. {
  182. $accountDividedLog = AccountDividedLog::where('pay_sn', $this->getParameter('orderId'))->get();
  183. (new WithdrawService($accountDividedLog))->handle();
  184. }
  185. /**
  186. * 保存支付订单记录
  187. * @return YopProOrder
  188. */
  189. protected function savePayOrder()
  190. {
  191. $pay_order = YopProOrder::paySn($this->getParameter('orderId'))->first();
  192. if(!is_null($pay_order)) {
  193. return $pay_order;
  194. }
  195. $data = [
  196. 'uniacid'=> \YunShop::app()->uniacid,
  197. 'merchantNo' => $this->getParameter('merchantNo'),
  198. 'pay_sn' => $this->getParameter('orderId'),
  199. 'yop_order_no' => $this->getParameter('uniqueOrderNo'),
  200. 'order_amount' => $this->getParameter('orderAmount'),
  201. 'pay_amount' => $this->getParameter('payAmount'),
  202. 'pay_success_at' => strtotime($this->getParameter('paySuccessDate')),
  203. 'platform_type' => $this->platformType(),
  204. 'payment_product' => $this->paymentProduct(),
  205. ];
  206. $yop_order = new YopProOrder();
  207. $yop_order->fill($data);
  208. $yop_order->save();
  209. return $yop_order;
  210. }
  211. //平台分类 支付类型
  212. protected function platformType()
  213. {
  214. $status = 0;
  215. if (!empty($this->getParameter('platformType'))) {
  216. switch ($this->getParameter('platformType')) {
  217. case 'WECHAT': //微信
  218. $status = YopProOrder::TYPE_WECHAT;
  219. break;
  220. case 'ALIPAY': //支付宝
  221. $status = YopProOrder::TYPE_ALIPAY;
  222. break;
  223. case 'NET':
  224. $status = YopProOrder::TYPE_NET;
  225. break;
  226. case 'NCPAY':
  227. $status = YopProOrder::TYPE_NCPAY;
  228. break;
  229. case 'CFL':
  230. $status = YopProOrder::TYPE_CFL;
  231. break;
  232. default:
  233. $status = 0;
  234. break;
  235. }
  236. }
  237. return $status;
  238. }
  239. //支付产品
  240. protected function paymentProduct()
  241. {
  242. $status = 0;
  243. if (!empty($this->getParameter('paymentProduct'))) {
  244. switch ($this->getParameter('paymentProduct')) {
  245. case 'WECHAT_OPENID': //微信公众号
  246. $status = YopProOrder::WECHAT_OPENID;
  247. break;
  248. case 'SCCANPAY': //用户扫码
  249. $status = YopProOrder::SCCANPAY;
  250. break;
  251. case 'MSCANPAY': //商家扫码
  252. $status = YopProOrder::MSCANPAY;
  253. break;
  254. case 'ZFB_SHH': //支付宝生活号
  255. $status = YopProOrder::ZFB_SHH;
  256. break;
  257. case 'ZF_ZHZF': //商户账户支付
  258. $status = YopProOrder::ZF_ZHZF;
  259. break;
  260. case 'EWALLETH5': //钱包H5支付
  261. $status = YopProOrder::EWALLETH5;
  262. break;
  263. default:
  264. $status = 0;
  265. break;
  266. }
  267. }
  268. return $status;
  269. }
  270. //订单实时分账返回
  271. public function divideNotifyUrl()
  272. {
  273. $this->debug('<---'.$this->getParameter('orderId').'--订单实时分账返回', $this->parameters);
  274. $accountDivided = AccountDivided::uniacid()->where('divide_no', $this->getParameter('divideRequestId'))->first();
  275. //记录存在只修改状态
  276. if ($accountDivided) {
  277. $this->debug('请求以存在--'.$this->getParameter('divideRequestId').'------>', $this->parameters);
  278. $accountDivided->status = $this->getParameter('status') == 'SUCCESS'?1:0;
  279. $accountDivided->save();
  280. echo 'SUCCESS'; exit();
  281. }
  282. $data = [
  283. 'uniacid' => \YunShop::app()->uniacid,
  284. 'merchantNo' => $this->getParameter('merchantNo'),
  285. 'pay_sn' => $this->getParameter('orderId'),
  286. 'yop_order_no' => $this->getParameter('uniqueOrderNo'),
  287. 'divide_no' => $this->getParameter('divideRequestId'),
  288. 'divide_detail' => json_decode($this->getParameter('divideDetail'), true),
  289. 'status' => $this->getParameter('status') == 'SUCCESS'?1:0,
  290. ];
  291. AccountDivided::create($data);
  292. $this->withdrawUpdate();
  293. echo 'SUCCESS'; exit();
  294. }
  295. //订单清算通知地址
  296. public function csUrl()
  297. {
  298. $yop_order = YopProOrder::where('yop_order_no', $this->getParameter('uniqueOrderNo'))
  299. ->where('pay_sn', $this->getParameter('orderId'))->first();
  300. if (!$yop_order) {
  301. \Log::debug('易宝专业版订单不存在无法清算',$this->parameters);
  302. exit('Record does not exist');
  303. }
  304. $data = [
  305. 'status' => 1,
  306. 'cs_at' => strtotime($this->getParameter('csSuccessDate')),
  307. 'merchant_fee' => $this->getParameter('merchantFee'),
  308. 'customer_fee' => $this->getParameter('customerFee'),
  309. ];
  310. $yop_order->fill($data);
  311. $yop_order->save();
  312. echo 'SUCCESS';exit();
  313. }
  314. //订单退款
  315. public function refundUrl()
  316. {
  317. $this->debug('-------------易宝订单退款通知---------------');
  318. $yop_refund = YopProOrderRefund::getRefundAnnal($this->getParameter('orderId'), $this->getParameter('refundRequestId'))
  319. ->where('status', YopProOrderRefund::REFUND)->first();
  320. if (!$yop_refund) {
  321. \Log::debug('易宝订单退款记录不存在pay_sn:'.$this->getParameter('orderId'),$this->parameters);
  322. exit('Record does not exist');
  323. }
  324. if ($yop_refund->status != YopProOrderRefund::REFUND) {
  325. \Log::debug('<-----------退款已处理---------------->', ['id'=>$yop_refund->id, 'pay_sn'=>$this->getParameter('orderId')]);
  326. echo 'SUCCESS';exit();
  327. }
  328. $yop_refund->status = $this->refundStatus();
  329. if ($this->getParameter('refundSuccessDate')) {
  330. $yop_refund->refund_at = strtotime($this->getParameter('refundSuccessDate'));
  331. }
  332. if ($this->getParameter('errorMessage')) {
  333. $yop_refund->error_message = $this->getParameter('errorMessage');
  334. }
  335. $yop_refund->save();
  336. echo 'SUCCESS';exit();
  337. }
  338. //退款状态
  339. protected function refundStatus()
  340. {
  341. $status = 0;
  342. if (!empty($this->parameters['status'])) {
  343. switch ($this->parameters['status']) {
  344. case 'FAILED':
  345. $status = YopProOrderRefund::REFUND_FAILED;
  346. break;
  347. case 'SUCCESS':
  348. $status = YopProOrderRefund::REFUND_SUCCESS;
  349. break;
  350. case 'CANCEL':
  351. $status = YopProOrderRefund::REFUND_CANCEL;
  352. break;
  353. default:
  354. $status = 0;
  355. break;
  356. }
  357. }
  358. return $status;
  359. }
  360. /**
  361. * 获取参数值
  362. * @param $parameter
  363. * @return string
  364. */
  365. public function getParameter($parameter)
  366. {
  367. return isset($this->parameters[$parameter])?$this->parameters[$parameter] : '';
  368. }
  369. //返回日志
  370. protected function debug($desc, $params = [])
  371. {
  372. \Yunshop\YopPro\common\YopProLog::log($desc, $params);
  373. }
  374. /**
  375. * 支付日志
  376. * @param $out_trade_no
  377. * @param $data
  378. * @param string $msg
  379. */
  380. public function log($out_trade_no, $data, $msg = '易宝pro支付')
  381. {
  382. //访问记录
  383. Pay::payAccessLog();
  384. //保存响应数据
  385. Pay::payResponseDataLog($out_trade_no, $msg, json_encode($data));
  386. }
  387. }