PayHandler.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. /**
  3. * 杉德支付
  4. * User: Ocean
  5. * Date: 2018/4/23
  6. * Time: 10:30
  7. */
  8. namespace common\pay\sand;
  9. use backend\models\Config;
  10. use backend\models\Deposit;
  11. use backend\models\SyncDesposit;
  12. use common\helpers\Utils;
  13. use common\pay\BasePayHandler;
  14. use Yii;
  15. use yii\helpers\VarDumper;
  16. class PayHandler extends BasePayHandler
  17. {
  18. public $payUrl;
  19. public $mid;
  20. public $certPwd;
  21. public $pubCert;
  22. public $priCert;
  23. /**
  24. * @inheritdoc
  25. */
  26. public function init()
  27. {
  28. parent::init();
  29. if ($this->payUrl == null) {
  30. $this->payUrl = Yii::$app->params['sand.payUrl'];
  31. }
  32. if ($this->mid == null) {
  33. $this->mid = Yii::$app->params['sand.mid'];
  34. }
  35. if ($this->certPwd == null) {
  36. $this->certPwd = Yii::$app->params['sand.certPwd'];
  37. }
  38. if ($this->pubCert == null) {
  39. $this->pubCert = __DIR__ . '/cert/sand.cer';
  40. }
  41. if ($this->priCert == null) {
  42. $this->priCert = __DIR__ . '/cert/private.pfx';
  43. }
  44. }
  45. /**
  46. * 去支付
  47. * @param array $params
  48. * @return array
  49. */
  50. public function outPay($deposit, $params)
  51. {
  52. $data['head'] = [
  53. 'version' => '1.0',
  54. 'method' => 'sandpay.trade.pay',
  55. 'accessType' => '1',
  56. 'productId' => '00000007',
  57. 'mid' => $this->mid,
  58. 'channelType' => '07',
  59. 'reqTime' => date('YmdHis', time())
  60. ];
  61. $data['body'] = [
  62. 'orderCode' => $deposit['order_sn'],
  63. 'totalAmount' => sprintf('%012s', $deposit['rmb'] * 100),
  64. 'subject' => 'RJ' . $deposit['order_sn'],
  65. 'body' => 'RJ' . $deposit['order_sn'],
  66. 'txnTimeOut' => date('YmdHis', time()+3600*10),
  67. 'payMode' => 'bank_pc',
  68. 'payExtra' => json_encode(['payType'=> 1,'bankCode' => $params['bankCode']]),
  69. 'clientIp' => isset($params['ip']) ? $params['ip'] : Utils::getClientIp(),
  70. 'notifyUrl' => $this->notifyUrl,
  71. 'frontUrl' => $this->returnUrl,
  72. 'extend' => ''
  73. ];
  74. $prikey = PayUtils::loadPk12Cert($this->priCert,$this->certPwd);
  75. $sign = PayUtils::sign($data, $prikey);
  76. $postData = [
  77. 'charset' => 'utf-8',
  78. 'signType' => '01',
  79. 'data' => json_encode($data),
  80. 'sign' => $sign
  81. ];
  82. Yii::warning('支付请求参数,' . VarDumper::dumpAsString($data), __METHOD__);
  83. $result = PayUtils::http_post_json( $this->payUrl,$postData);
  84. parse_str(urldecode($result), $arr);
  85. $arr['data'] = str_replace(array(" ","\t","\n","\r"),array('','','',''),$arr['data']);
  86. $data = json_decode($arr['data'],true);
  87. $credential = json_decode($data['body']['credential'],true);
  88. if(isset($credential['params']['orig']) && isset($credential['params']['sign']) ){
  89. $arr['data']= PayUtils::mb_array_chunk($data);
  90. $arr['data'] = str_replace(array("\\\/","\\/","\/"),array("/","/","/"), $arr['data']);
  91. }else {
  92. $data['body']['credential'] = PayUtils::json_encodes($credential);
  93. $arr['data'] = str_replace(array("\\\/","\\/","\/"," "),array("/","/","/","+"),PayUtils::json_encodes($data));
  94. }
  95. $arr['sign'] = preg_replace('/\s/', '+', $arr['sign']);
  96. try{
  97. PayUtils::verify($arr['data'], $arr['sign'], $this->pubCert);
  98. }catch (\Exception $e){
  99. Yii::warning('签名失败,' . VarDumper::dumpAsString($e->getMessage()), __METHOD__);
  100. }
  101. $data = json_decode($arr['data'],320);
  102. // return $data;
  103. if ($data['head']['respCode'] == "000000" ) {
  104. $credential = str_replace(array('"{','}"'),array('{','}'),stripslashes($data['body']['credential']));
  105. }
  106. Yii::warning('支付请求结果,' . VarDumper::dumpAsString($credential), __METHOD__);
  107. return $credential;
  108. return $this->payJump($credential);
  109. }
  110. /**
  111. * 支付跳转HTML拼接
  112. * @param $credential
  113. * @return string
  114. */
  115. public function payJump($credential)
  116. {
  117. $html = <<<eot
  118. <script>
  119. function wap_pay() {
  120. var responseText = $("#credential").text();
  121. //console.log(responseText);
  122. paymentjs.createPayment(responseText, function(result, err) {
  123. //console.log(result);
  124. //console.log(err.msg);
  125. //console.log(err.extra);
  126. });
  127. }
  128. </script>
  129. <div style="display: none" >
  130. <p id="credential">$credential</p>
  131. </div>
  132. eot;
  133. return $html;
  134. }
  135. /**
  136. * 处理异步回调
  137. * @param array $params
  138. * @return array
  139. */
  140. public function handleNotify($params)
  141. {
  142. Yii::warning('支付异步通知参数,' . VarDumper::dumpAsString($params), __METHOD__);
  143. $sign = $params['sign']; //签名
  144. $signType = $params['signType']; //签名方式
  145. $data = stripslashes($params['data']); //支付数据
  146. $charset = $params['charset']; //支付编码
  147. $result = json_decode($data,true); //data数据
  148. Yii::warning('支付异步通知参数sand,' . VarDumper::dumpAsString($result), __METHOD__);
  149. $merOrderId = $result['body']['orderCode'];
  150. if (PayUtils::verify($data, $sign, $this->pubCert)) {
  151. Yii::warning('支付异步通知认证签名成功,' . VarDumper::dumpAsString($data), __METHOD__);
  152. $reuslt = Deposit::find()->where(['order_sn' => $merOrderId])->asArray()->limit(1)->one();
  153. if ($reuslt['type'] != 1) {
  154. $res = Deposit::updateAll(['type' => 1], "order_sn = $merOrderId");
  155. $configData = Config::find()->asArray()->one();
  156. if ($configData['auto_deposit'] == 1 && $res) {
  157. $syncDespositModel = new SyncDesposit();
  158. $syncDespositModel->login = $reuslt['login'];
  159. $syncDespositModel->amount = $reuslt['amount'];
  160. $syncDespositModel->comment = 'Deposit';
  161. $syncDespositModel->memo = $merOrderId;
  162. $syncDespositModel->type = 2;
  163. $syncDespositModel->in_time = time();
  164. $syncDespositModel->save();
  165. }
  166. return true;
  167. }
  168. } else {
  169. Yii::warning('支付异步通知认证签名失败,' . VarDumper::dumpAsString($data), __METHOD__);
  170. return false;
  171. }
  172. return false;
  173. }
  174. /**
  175. * @param bool $success
  176. * @return string
  177. */
  178. public function outNotify($success)
  179. {
  180. if ($success == true) {
  181. return 'respCode=000000';
  182. } else {
  183. return 'fail';
  184. }
  185. }
  186. /**
  187. * 处理同步回调
  188. * @param array $params
  189. * @return array
  190. */
  191. public function handleReturn($params)
  192. {
  193. Yii::warning('支付同步通知参数,' . VarDumper::dumpAsString($params), __METHOD__);
  194. $sign = $params['sign']; //签名
  195. $signType = $params['signType']; //签名方式
  196. $data = stripslashes($params['data']); //支付数据
  197. $charset = $params['charset']; //支付编码
  198. $result = json_decode($data,true); //data数据
  199. $merOrderId = $result['body']['orderCode'];
  200. if (PayUtils::verify($data, $sign, $this->pubCert)) {
  201. $reuslt = Deposit::find()->where(['order_sn' => $merOrderId])->asArray()->limit(1)->one();
  202. if ($reuslt['type'] != 1) {
  203. Deposit::updateAll(['type' => 1], "order_sn = $merOrderId");
  204. $configData = Config::find()->asArray()->one();
  205. if ($configData['auto_deposit'] == 1) {
  206. $syncDespositModel = new SyncDesposit();
  207. $syncDespositModel->login = $reuslt['login'];
  208. $syncDespositModel->amount = $reuslt['amount'];
  209. $syncDespositModel->comment = 'Deposit';
  210. $syncDespositModel->memo = $merOrderId;
  211. $syncDespositModel->type = 2;
  212. $syncDespositModel->in_time = time();
  213. $syncDespositModel->save();
  214. }
  215. return true;
  216. }
  217. } else {
  218. Yii::warning('支付同步通知认证签名失败,' . VarDumper::dumpAsString($params), __METHOD__);
  219. return false;
  220. }
  221. return false;
  222. }
  223. /**
  224. * @param bool $success
  225. */
  226. public function outReturn($success)
  227. {
  228. }
  229. }