You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
3.2 KiB

  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: travis
  5. * Date: 2019/12/12
  6. * Time: 6:20
  7. */
  8. namespace api\logic;
  9. use backend\modules\payment\logic\WxPaymentManager;
  10. use yii\helpers\Json;
  11. use yii\httpclient\Client;
  12. use yii\web\BadRequestHttpException;
  13. use backend\modules\shop\models\ars\PaymentLog;
  14. use yii\db\Exception;
  15. use Yii;
  16. class WxPaymentLogic extends WxPaymentManager
  17. {
  18. /**
  19. * @return array|bool
  20. * @throws BadRequestHttpException
  21. * @throws \yii\base\InvalidConfigException
  22. * @throws \yii\httpclient\Exception
  23. * 微信支付回调
  24. */
  25. public function notify()
  26. {
  27. $notifyData = Json::decode(Json::encode(simplexml_load_string(Yii::$app->request->getRawBody(), 'SimpleXMLElement', LIBXML_NOCDATA)));
  28. Yii::info($notifyData, "notify");
  29. if (!$this->checkSign($notifyData)) {
  30. throw new BadRequestHttpException(Helper::REQUEST_BAD_PARAMS);
  31. }
  32. $tra = Yii::$app->db->beginTransaction('SERIALIZABLE');
  33. try {
  34. if ($notifyData->result_code != 'SUCCESS' || $notifyData->return_code != 'SUCCESS') {
  35. throw new BadRequestHttpException('result_code or return_code is false');
  36. }
  37. $paymentLog = PaymentLog::findOne(['order_id' => $notifyData->out_trade_no]);
  38. $this->notifyUrl = Yii::$app->request->hostInfo . $paymentLog->notify_url;
  39. $paymentLog->mch_id = $notifyData->mch_id;
  40. $paymentLog->wx_payment_id = $notifyData->transaction_id; //交易号
  41. $paymentLog->status = self::STATUS_PAYMENT_SUCCESS;
  42. $paymentLog->payment_at = time();
  43. if (!$paymentLog->save()) {
  44. throw new Exception(Helper::errorMessageStr($paymentLog->errors));
  45. }
  46. if (!$tra->commit()) {
  47. throw new Exception('保存数据失败');
  48. }
  49. /*转发回调信息*/
  50. $this->forwardNotify($notifyData, true);
  51. return ['return_code' => 'SUCCESS', 'return_msg' => 'OK'];//回传成功信息到微信服务器
  52. } catch (Exception $e) {
  53. $tra->rollBack();
  54. $this->forwardNotify($notifyData, false);
  55. Yii::info($e->getMessage(), 'notify');
  56. return false;
  57. } catch (BadRequestHttpException $e) {
  58. $tra->rollBack();
  59. $this->forwardNotify($notifyData, false);
  60. Yii::info($e->getMessage(), 'notify');
  61. return false;
  62. }
  63. }
  64. /**
  65. * @param $notifyData
  66. * @param $status
  67. * @return bool
  68. * @throws \yii\base\InvalidConfigException
  69. * @throws \yii\httpclient\Exception
  70. * 转发异步回调信息
  71. */
  72. protected function forwardNotify($notifyData, $status)
  73. {
  74. $notify = [
  75. 'notify' => [
  76. 'status' => $status,
  77. 'notify' => $notifyData
  78. ]
  79. ];
  80. $client = new Client();
  81. $response = $client->createRequest()
  82. ->setMethod('POST')
  83. ->setUrl($this->notifyUrl)
  84. ->addHeaders(['content-type' => 'application/json'])
  85. ->setContent(Json::encode($notify))
  86. ->send();
  87. if ($response->isOk) {
  88. return true;
  89. } else {
  90. return false;
  91. }
  92. }
  93. }