FastPayService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. <?php
  2. namespace addons\UnionPay\common\service;
  3. use addons\UnionPay\common\enums\UnionPayEnum;
  4. use addons\UnionPay\common\models\UnionpayRequestLog;
  5. use addons\UnionPay\common\models\UnionpayUserBankCard;
  6. use common\models\common\PaymentTrade;
  7. use common\models\common\UserBankCard;
  8. use yii\db\Exception;
  9. use \Yii;
  10. class FastPayService extends PayService
  11. {
  12. public $yl_api_url = "https://vsp.allinpay.com/apiweb/qpay";// 快捷支付
  13. //快捷支付签约申请
  14. public function sendSignSms(UnionpayUserBankCard $unionpay_user_bankcard_model, UserBankCard $user_band_card)
  15. {
  16. $config = \Yii::$app->services->setting->addons->get($unionpay_user_bankcard_model->mall_id, UnionPayEnum::ADDONS_NAME, 'basic');
  17. $card_type = strtolower($user_band_card->card_type);
  18. $accttype = '';
  19. switch ($card_type) {
  20. case 'dc':
  21. $accttype = '00';
  22. break;
  23. case 'cc':
  24. $accttype = '02';
  25. }
  26. $params = [];
  27. $params["cusid"] = $config['cusid'];
  28. $params["appid"] = $config['appid'];
  29. $params["orgid"] = $config['orgid'];
  30. $params["version"] = $this->version;
  31. $params["randomstr"] = md5(microtime(true));
  32. $params["signtype"] = $this->sign_type;
  33. $params["meruserid"] = $user_band_card->user_id;
  34. $params["accttype"] = $accttype;
  35. $params["acctno"] = $user_band_card->bank_card_no;
  36. $params["idtype"] = $unionpay_user_bankcard_model->id_type;
  37. $params["idno"] = $unionpay_user_bankcard_model->id_no;
  38. $params["acctname"] = $user_band_card->payer_name;
  39. $params["mobile"] = $unionpay_user_bankcard_model->mobile;
  40. $params["validdate"] = $unionpay_user_bankcard_model->validdate;
  41. $params["cvv2"] = $unionpay_user_bankcard_model->cvv2;
  42. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  43. $params_str = $this->ToUrlParams($params);
  44. $url = $this->yl_api_url . "/agreeapply";
  45. $rsp = $this->request($url, $params_str);
  46. $add_data = [
  47. 'type' => 'agreeapply',
  48. 'out_trade_no' => '',
  49. 'oldtrxid' => '',
  50. 'trade_type' => '',
  51. 'randomstr' => $params["randomstr"],
  52. 'request_data' => $params_str,
  53. 'response_data' => $rsp
  54. ];
  55. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  56. $rsp = json_decode($rsp, true);
  57. if ($rsp['retcode'] != 'SUCCESS') {
  58. $msg = $rsp['retmsg'] ?? '系统内部错误';
  59. throw new Exception($msg);
  60. }
  61. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  62. throw new Exception('验签失败');
  63. }
  64. if ($rsp['trxstatus'] != '1999') {
  65. throw new Exception($rsp['errmsg']);
  66. }
  67. $rsp['card_id'] = $user_band_card->id;
  68. return [
  69. 'data' => ['agreeid' => $unionpay_user_bankcard_model->sign_no,
  70. 'back_image' => UserBankCard::getBankPicture($user_band_card->bank_code),
  71. 'bank_account_type' => $user_band_card->bank_account_type,
  72. 'bank_card_no' => $user_band_card->bank_card_no,
  73. 'bank_code' => $user_band_card->bank_code,
  74. 'bank_name' => $user_band_card->bank_name,
  75. 'card_type' => $user_band_card->card_type,
  76. 'card_type_name' => $user_band_card->card_type_name,
  77. 'created_at' => $user_band_card->created_at,
  78. 'icon' => UserBankCard::getBankPicture($user_band_card->bank_code),
  79. 'id' => $user_band_card->id,
  80. 'is_sign' => $unionpay_user_bankcard_model->is_sign,
  81. 'mall_id' => $user_band_card->mall_id,
  82. 'payer_name' => $user_band_card->payer_name,
  83. 'status' => $user_band_card->status,
  84. 'updated_at' => $user_band_card->updated_at,
  85. 'user_id' => $user_band_card->user_id,
  86. ],
  87. 'card_id' => $user_band_card->id,
  88. 'id_no' => $unionpay_user_bankcard_model->id_no,
  89. 'mobile' => $unionpay_user_bankcard_model->mobile,
  90. 'cvv2' => $unionpay_user_bankcard_model->cvv2,
  91. 'validdate' => $unionpay_user_bankcard_model->validdate,
  92. 'thpinfo' => $rsp['thpinfo'],
  93. 'trxstatus' => $rsp['trxstatus']
  94. ];
  95. }
  96. //签约申请确认
  97. public function agreeConfirm($mall_id, $user_id, $card_id, $smscode, $thpinfo)
  98. {
  99. $user_band_card = UserBankCard::findOne(['id' => $card_id]);
  100. $unionpay_user_bankcard_model = UnionpayUserBankCard::findOne(['card_id' => $card_id]);
  101. $config = \Yii::$app->services->setting->addons->get($mall_id, UnionPayEnum::ADDONS_NAME, 'basic');
  102. $card_type = strtolower($user_band_card->card_type);
  103. $accttype = '';
  104. switch ($card_type) {
  105. case 'dc':
  106. $accttype = '00';
  107. break;
  108. case 'cc':
  109. $accttype = '02';
  110. }
  111. $params = [];
  112. $params["cusid"] = $config['cusid'];
  113. $params["appid"] = $config['appid'];
  114. $params["orgid"] = $config['orgid'];
  115. $params["version"] = $this->version;
  116. $params["reqtime"] = date('YmdHis', time());
  117. $params["meruserid"] = $user_id;
  118. $params["accttype"] = $accttype;
  119. $params["acctno"] = $user_band_card->bank_card_no;
  120. $params["idtype"] = $unionpay_user_bankcard_model->id_type;
  121. $params["idno"] = $unionpay_user_bankcard_model->id_no;
  122. $params["acctname"] = $user_band_card->payer_name;
  123. $params["mobile"] = $unionpay_user_bankcard_model->mobile;
  124. $params["validdate"] = $unionpay_user_bankcard_model->validdate;
  125. $params["cvv2"] = $unionpay_user_bankcard_model->cvv2;
  126. $params["smscode"] = $smscode;
  127. $params["thpinfo"] = $thpinfo;
  128. $params["randomstr"] = md5(microtime(true));
  129. $params["signtype"] = $this->sign_type;
  130. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  131. $params_str = $this->toUrlParams($params);
  132. $url = $this->yl_api_url . "/agreeconfirm";
  133. $rsp = $this->request($url, $params_str);
  134. $add_data = [
  135. 'type' => 'agreeconfirm',
  136. 'out_trade_no' => '',
  137. 'oldtrxid' => '',
  138. 'trade_type' => '',
  139. 'randomstr' => $params["randomstr"],
  140. 'request_data' => $params_str,
  141. 'response_data' => $rsp
  142. ];
  143. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  144. $rsp = json_decode($rsp, true);
  145. if ($rsp['retcode'] != 'SUCCESS') {
  146. $msg = $rsp['retmsg'] ?? '系统内部错误';
  147. throw new Exception($msg);
  148. }
  149. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  150. throw new Exception('验签失败');
  151. }
  152. if (empty($rsp['agreeid']) || $rsp['trxstatus'] != '0000') {
  153. throw new Exception($rsp['errmsg']);
  154. }
  155. $unionpay_user_bankcard_model->sign_no = $rsp['agreeid'];
  156. $unionpay_user_bankcard_model->is_sign = 1;
  157. $unionpay_user_bankcard_model->save();
  158. $user_band_card->bank_code = $rsp['bankcode'];
  159. $user_band_card->bank_name = $rsp['bankname'];
  160. $user_band_card->save();
  161. return [
  162. 'data' => ['agreeid' => $unionpay_user_bankcard_model->sign_no,
  163. 'back_image' => UserBankCard::getBankPicture($user_band_card->bank_code),
  164. 'bank_account_type' => $user_band_card->bank_account_type,
  165. 'bank_card_no' => $user_band_card->bank_card_no,
  166. 'bank_code' => $user_band_card->bank_code,
  167. 'bank_name' => $user_band_card->bank_name,
  168. 'card_type' => $user_band_card->card_type,
  169. 'card_type_name' => $user_band_card->card_type_name,
  170. 'created_at' => $user_band_card->created_at,
  171. 'icon' => UserBankCard::getBankPicture($user_band_card->bank_code),
  172. 'id' => $user_band_card->id,
  173. 'is_sign' => $unionpay_user_bankcard_model->is_sign,
  174. 'mall_id' => $user_band_card->mall_id,
  175. 'payer_name' => $user_band_card->payer_name,
  176. 'status' => $user_band_card->status,
  177. 'updated_at' => $user_band_card->updated_at,
  178. 'user_id' => $user_band_card->user_id,
  179. ],
  180. 'card_id' => $user_band_card->id,
  181. 'trxstatus' => $rsp['trxstatus'],
  182. 'errmsg' => $rsp['errmsg']
  183. ];
  184. }
  185. //商户支付申请
  186. public function payapplyagree($user_id, $card_id, $trade_no)
  187. {
  188. $trade = PaymentTrade::findOne(['mall_id' => $this->mall_id, 'user_id' => $user_id, 'out_trade_no' => $trade_no]);
  189. $config = \Yii::$app->services->setting->addons->get($trade->mall_id, UnionPayEnum::ADDONS_NAME, 'basic');
  190. $unionpay_user_bankcard_model = UnionpayUserBankCard::findOne(['user_id' => $trade->user_id, 'card_id' => $card_id]);
  191. if (empty($unionpay_user_bankcard_model)) throw new Exception('用户银行卡未签约');
  192. $params = [];
  193. $params["cusid"] = $config['cusid'];
  194. $params["appid"] = $config['appid'];
  195. $params["orgid"] = $config['orgid'];
  196. $params["version"] = $this->version;
  197. $params["randomstr"] = md5(microtime(true));
  198. $params["signtype"] = $this->sign_type;
  199. $params["reqtime"] = date('YmdHis', time());
  200. $params["agreeid"] = $unionpay_user_bankcard_model->sign_no;
  201. $params["amount"] = $trade->pay_fee * 100;
  202. $params["reqsn"] = $trade->out_trade_no;
  203. $params["currency"] = 'CNY';
  204. $params["subject"] = $trade->title;
  205. $params["notifyurl"] = \Yii::$app->services->setting->platform->get('system.api_url') . "/union-pay/notify/notify";
  206. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  207. $params_str = $this->ToUrlParams($params);
  208. $url = $this->yl_api_url . "/payapplyagree";
  209. $rsp = $this->request($url, $params_str);
  210. $add_data = [
  211. 'type' => 'payapplyagree',
  212. 'out_trade_no' => $trade->out_trade_no,
  213. 'oldtrxid' => '',
  214. 'trade_type' => $trade->trade_type,
  215. 'randomstr' => $params["randomstr"],
  216. 'request_data' => $params_str,
  217. 'response_data' => $rsp
  218. ];
  219. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  220. $rsp = json_decode($rsp, true);
  221. if ($rsp['retcode'] != 'SUCCESS') {
  222. $msg = $rsp['retmsg'] ?? '系统内部错误';
  223. throw new Exception($msg);
  224. }
  225. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  226. throw new Exception('验签失败');
  227. }
  228. if ($rsp['trxstatus'] == '0000' || $rsp['trxstatus'] == '1999') {
  229. Yii::error('payapplyagree::response' . json_encode($rsp));
  230. $trade->trade_type = 'fast_pay';
  231. $trade->save();
  232. } else {
  233. throw new Exception($rsp['errmsg']);
  234. }
  235. return ['errmsg' => $rsp['errmsg'], 'reqsn' => $rsp['reqsn'], 'thpinfo' => $rsp['thpinfo'], 'trxstatus' => $rsp['trxstatus']];
  236. }
  237. //支付确认
  238. public function payagreeconfirm($mall_id, $user_id, $trade_no, $card_id, $thpinfo, $smscode)
  239. {
  240. $trade = PaymentTrade::findOne(['user_id' => $user_id, 'out_trade_no' => $trade_no]);
  241. $unionpay_user_bankcard_model = UnionpayUserBankCard::findOne(['user_id' => $user_id, 'card_id' => $card_id]);
  242. $config = \Yii::$app->services->setting->addons->get($mall_id, UnionPayEnum::ADDONS_NAME, 'basic');
  243. $params = [];
  244. $params["cusid"] = $config['cusid'];
  245. $params["appid"] = $config['appid'];
  246. $params["orgid"] = $config['orgid'];
  247. $params["version"] = $this->version;
  248. $params["randomstr"] = md5(microtime(true));
  249. $params["signtype"] = $this->sign_type;
  250. $params["reqtime"] = date('YmdHis', time());
  251. $params["amount"] = $trade->pay_fee * 100;
  252. $params["currency"] = 'CNY';
  253. $params["reqsn"] = $trade->out_trade_no;
  254. $params["agreeid"] = $unionpay_user_bankcard_model->sign_no;
  255. $params["smscode"] = $smscode;
  256. $params["thpinfo"] = $thpinfo;
  257. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  258. $params_str = $this->toUrlParams($params);
  259. $url = $this->yl_api_url . "/payagreeconfirm";
  260. $rsp = $this->request($url, $params_str);
  261. $rsp = json_decode($rsp, true);
  262. $add_data = [
  263. 'type' => 'payagreeconfirm',
  264. 'out_trade_no' => $trade->out_trade_no,
  265. 'oldtrxid' => $rsp['trxid'] ?? '',
  266. 'trade_type' => $trade->trade_type,
  267. 'randomstr' => $params["randomstr"],
  268. 'request_data' => $params_str,
  269. 'response_data' => json_encode($rsp)
  270. ];
  271. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  272. if ($rsp['retcode'] != 'SUCCESS') {
  273. $msg = $rsp['retmsg'] ?? '系统内部错误';
  274. throw new Exception($msg);
  275. }
  276. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  277. throw new Exception('验签失败');
  278. }
  279. if ($rsp['trxstatus'] == '0000') {
  280. $trade->third_trade_no = $rsp['trxid'];
  281. $trade->save();
  282. } else {
  283. throw new Exception($rsp['errmsg']);
  284. }
  285. return ['fintime' => $rsp['fintime'], 'amount' => $trade->pay_fee, 'reqsn' => $rsp['reqsn'], 'trxid' => $rsp['trxid'], 'trxstatus' => $rsp['trxstatus']];
  286. }
  287. //重新获取支付短信
  288. public function paysmsagree($mall_id, $user_id, $card_id, $trade_no, $thpinfo)
  289. {
  290. $config = \Yii::$app->services->setting->addons->get($mall_id, UnionPayEnum::ADDONS_NAME, 'basic');
  291. $unionpay_user_bankcard_model = UnionpayUserBankCard::findOne(['card_id' => $card_id]);
  292. $params = [];
  293. $params["cusid"] = $config['cusid'];
  294. $params["appid"] = $config['appid'];
  295. $params["orgid"] = $config['orgid'];
  296. $params["version"] = $this->version;
  297. $params["reqtime"] = date('YmdHis', time());
  298. $params["randomstr"] = md5(microtime(true));
  299. $params["signtype"] = $this->sign_type;
  300. $params["meruserid"] = $user_id;
  301. $params["orderid"] = $trade_no;
  302. $params["agreeid"] = $unionpay_user_bankcard_model->sign_no;
  303. $params["thpinfo"] = $thpinfo;
  304. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  305. $params_str = $this->toUrlParams($params);
  306. $url = $this->yl_api_url . "/paysmsagree";
  307. $rsp = $this->request($url, $params_str);
  308. $rsp = json_decode($rsp, true);
  309. $add_data = [
  310. 'type' => 'paysmsagree',
  311. 'out_trade_no' => $trade_no,
  312. 'oldtrxid' => $rsp['trxid'] ?? '',
  313. 'trade_type' => 'fat_pay',
  314. 'randomstr' => $params["randomstr"],
  315. 'request_data' => $params_str,
  316. 'response_data' => json_encode($rsp)
  317. ];
  318. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  319. if ($rsp['retcode'] != 'SUCCESS') {
  320. $msg = $rsp['retmsg'] ?? '系统内部错误';
  321. throw new Exception($msg);
  322. }
  323. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  324. throw new Exception('验签失败');
  325. }
  326. if (!empty($rsp['errmsg'])) {
  327. throw new Exception($rsp['errmsg']);
  328. }
  329. return $rsp;
  330. }
  331. //银行卡解绑接口
  332. public function unbind($user_id, $card_id)
  333. {
  334. $config = $this->config;
  335. $unionpay_user_bankcard_model = UnionpayUserBankCard::findOne(['mall_id' => $this->mall_id, 'user_id' => $user_id, 'card_id' => $card_id]);
  336. $params = [];
  337. $params["cusid"] = $config['cusid'];
  338. $params["appid"] = $config['appid'];
  339. $params["orgid"] = $config['orgid'];
  340. $params["version"] = $this->version;
  341. $params["randomstr"] = md5(microtime(true));
  342. $params["signtype"] = $this->sign_type;
  343. $params["agreeid"] = $unionpay_user_bankcard_model->sign_no;
  344. $params["sign"] = urlencode($this->sign($params, $config['private_key']));//签名
  345. $params_str = $this->toUrlParams($params);
  346. $url = $this->yl_api_url . "/unbind";
  347. $rsp = $this->request($url, $params_str);
  348. $add_data = [
  349. 'type' => 'unbind',
  350. 'out_trade_no' => '',
  351. 'oldtrxid' => '',
  352. 'trade_type' => 'fat_pay',
  353. 'randomstr' => $params["randomstr"],
  354. 'request_data' => $params_str,
  355. 'response_data' => $rsp
  356. ];
  357. UnionpayRequestLog::setData($unionpay_user_bankcard_model->mall_id, $add_data);
  358. $rsp = json_decode($rsp, true);
  359. if ($rsp['retcode'] != 'SUCCESS') {
  360. $msg = $rsp['retmsg'] ?? '系统内部错误';
  361. throw new Exception($msg);
  362. }
  363. if (!$this->validSign($rsp, $config['union_pay_public_key'])) {
  364. throw new Exception('验签失败');
  365. }
  366. $unionpay_user_bankcard_model->is_sign = 0;
  367. $unionpay_user_bankcard_model->sign_no = '';
  368. $unionpay_user_bankcard_model->save();
  369. return $rsp;
  370. }
  371. }