JoinpayPaymentService.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. namespace app\data\service\payment;
  3. use app\data\service\PaymentService;
  4. use think\admin\Exception;
  5. use think\admin\extend\HttpExtend;
  6. /**
  7. * 汇聚支付基础服务
  8. * Class JoinpayPaymentService
  9. * @package app\data\service\payment
  10. */
  11. class JoinpayPaymentService extends PaymentService
  12. {
  13. /**
  14. * 请求地址
  15. * @var string
  16. */
  17. protected $uri;
  18. /**
  19. * 应用编号
  20. * @var string
  21. */
  22. protected $appid;
  23. /**
  24. * 报备商户号
  25. * @var string
  26. */
  27. protected $trade;
  28. /**
  29. * 平台商户号
  30. * @var string
  31. */
  32. protected $mchid;
  33. /**
  34. * 平台商户密钥
  35. * @var string
  36. */
  37. protected $mchkey;
  38. /**
  39. * 创建订单支付参数
  40. * @param string $openid 用户OPENID
  41. * @param string $orderNo 交易订单单号
  42. * @param string $payAmount 交易订单金额(元)
  43. * @param string $payTitle 交易订单名称
  44. * @param string $payRemark 订单订单描述
  45. * @param string $payReturn 完成回跳地址
  46. * @param string $payImage 支付凭证图片
  47. * @return array
  48. * @throws Exception
  49. */
  50. public function create(string $openid, string $orderNo, string $payAmount, string $payTitle, string $payRemark, string $payReturn = '', string $payImage = ''): array
  51. {
  52. try {
  53. if (isset(static::TYPES[$this->type])) {
  54. $tradeType = static::TYPES[$this->type]['type'];
  55. } else {
  56. throw new Exception(sprintf('支付类型[%s]未配置定义!', $this->type));
  57. }
  58. $data = [
  59. 'p0_Version' => '1.0',
  60. 'p1_MerchantNo' => $this->mchid,
  61. 'p2_OrderNo' => $orderNo,
  62. 'p3_Amount' => $payAmount,
  63. 'p4_Cur' => '1',
  64. 'p5_ProductName' => $payTitle,
  65. 'p6_ProductDesc' => $payRemark,
  66. 'p9_NotifyUrl' => sysuri("@data/api.notify/joinpay/scene/order/param/{$this->code}", [], false, true),
  67. 'q1_FrpCode' => $tradeType ?? '',
  68. 'q5_OpenId' => $openid,
  69. 'q7_AppId' => $this->appid,
  70. 'qa_TradeMerchantNo' => $this->trade,
  71. ];
  72. if (empty($data['q5_OpenId'])) unset($data['q5_OpenId']);
  73. $this->uri = 'https://www.joinpay.com/trade/uniPayApi.action';
  74. $result = $this->_doReuest($data);
  75. if (isset($result['ra_Code']) && intval($result['ra_Code']) === 100) {
  76. // 创建支付记录
  77. $this->createPaymentAction($orderNo, $payTitle, $payAmount);
  78. // 返回支付参数
  79. return json_decode($result['rc_Result'], true);
  80. } elseif (isset($result['rb_CodeMsg'])) {
  81. throw new Exception($result['rb_CodeMsg']);
  82. } else {
  83. throw new Exception('获取预支付码失败!');
  84. }
  85. } catch (Exception $exception) {
  86. throw $exception;
  87. } catch (\Exception $exception) {
  88. throw new Exception($exception->getMessage(), $exception->getCode());
  89. }
  90. }
  91. /**
  92. * 执行数据请求
  93. * @param array $data
  94. * @return array
  95. */
  96. private function _doReuest(array $data = []): array
  97. {
  98. $data['hmac'] = $this->_doSign($data);
  99. return json_decode(HttpExtend::post($this->uri, $data), true);
  100. }
  101. /**
  102. * 请求数据签名
  103. * @param array $data
  104. * @return string
  105. */
  106. private function _doSign(array $data): string
  107. {
  108. ksort($data);
  109. unset($data['hmac']);
  110. return md5(join('', $data) . $this->mchkey);
  111. }
  112. /**
  113. * 查询订单数据
  114. * @param string $orderNo
  115. * @return array
  116. */
  117. public function query(string $orderNo): array
  118. {
  119. $this->uri = 'https://www.joinpay.com/trade/queryOrder.action';
  120. return $this->_doReuest(['p1_MerchantNo' => $this->mchid, 'p2_OrderNo' => $orderNo]);
  121. }
  122. /**
  123. * 支付结果处理
  124. * @return string
  125. */
  126. public function notify(): string
  127. {
  128. $notify = $this->app->request->get();
  129. foreach ($notify as &$item) $item = urldecode($item);
  130. if (empty($notify['hmac']) || $notify['hmac'] !== $this->_doSign($notify)) {
  131. return 'error';
  132. }
  133. if (isset($notify['r6_Status']) && intval($notify['r6_Status']) === 100) {
  134. if ($this->updatePaymentAction($notify['r2_OrderNo'], $notify['r9_BankTrxNo'], $notify['r3_Amount'])) {
  135. return 'success';
  136. } else {
  137. return 'error';
  138. }
  139. } else {
  140. return 'success';
  141. }
  142. }
  143. /**
  144. * 汇聚支付服务初始化
  145. * @return JoinpayPaymentService
  146. */
  147. protected function initialize(): JoinpayPaymentService
  148. {
  149. $this->appid = $this->params['joinpay_appid'];
  150. $this->trade = $this->params['joinpay_trade'];
  151. $this->mchid = $this->params['joinpay_mch_id'];
  152. $this->mchkey = $this->params['joinpay_mch_key'];
  153. return $this;
  154. }
  155. }