SanJinService.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. <?php
  2. namespace App\Services\Payment;
  3. use GuzzleHttp\Client;
  4. use GuzzleHttp\Exception\RequestException;
  5. use GuzzleHttp\Psr7\Response;
  6. use App\Services\BaseService;
  7. use Illuminate\Support\Facades\Lang;
  8. class SanJinService extends BaseService
  9. {
  10. const REQUEST_URL = 'https://jkapi-sanjin.jkcbb.com/';
  11. const PRODUCT_TEST = 'T888'; // 测试支付通道
  12. public static $CHANNEL = [
  13. 'wxsm' => '微信扫码',
  14. 'zfbsm' => '支付宝扫码',
  15. 'zfbge' => '支付宝固额',
  16. 'zfbzk' => '支付宝转卡',
  17. 'ylsm' => '银联扫码',
  18. 'szrmb' => '数字人民币',
  19. 'sdjt' => '手动金条',
  20. ];
  21. /**
  22. * @description: 获取支付频道
  23. * @return {*}
  24. */
  25. public static function getChannel($key = '')
  26. {
  27. $channel = self::$CHANNEL;
  28. if($key){
  29. return Lang($channel[$key]);
  30. }else{
  31. foreach($channel as $k => $v){
  32. $channel[$k] = lang($v);
  33. }
  34. return $channel;
  35. }
  36. }
  37. public static $PRODUCT = [
  38. // 'T888' => [
  39. // 'type' => 'test',
  40. // 'rate' => 0.02,
  41. // 'max' => 5000,
  42. // 'min' => 10
  43. // ],
  44. 'WX002' => [
  45. 'type' => 'wxsm',
  46. 'rate' => 0.095,
  47. 'max' => 3000,
  48. 'min' => 100
  49. ],
  50. 'YL001' => [
  51. 'type' => 'ylsm',
  52. 'rate' => 0.05,
  53. 'max' => 500,
  54. 'min' => 50
  55. ],
  56. 'SZ002' => [
  57. 'type' => 'szrmb',
  58. 'rate' => 0.05,
  59. 'max' => 100,
  60. 'min' => 10
  61. ],
  62. 'SZ001' => [
  63. 'type' => 'szrmb',
  64. 'rate' => 0.048,
  65. 'max' => 5000,
  66. 'min' => 100
  67. ],
  68. 'ZFB001' => [
  69. 'type' => 'zfbsm',
  70. 'rate' => 0.085,
  71. 'max' => 200,
  72. 'min' => 100
  73. ],
  74. 'ZFB002' => [
  75. 'type' => 'zfbsm',
  76. 'rate' => 0.057,
  77. 'max' => 1000,
  78. 'min' => 200
  79. ],
  80. 'ZFB003' => [
  81. 'type' => 'zfbsm',
  82. 'rate' => 0.052,
  83. 'max' => 3000,
  84. 'min' => 1000
  85. ],
  86. 'ZFB004' => [
  87. 'type' => 'zfbsm',
  88. 'rate' => 0.042,
  89. 'max' => 20000,
  90. 'min' => 3000
  91. ],
  92. 'ZFB005' => [
  93. 'type' => 'zfbge',
  94. 'rate' => 0.027,
  95. 'fixed' => [945 ,988 ,990]
  96. ],
  97. 'ZFBZK001' => [
  98. 'type' => 'zfbzk',
  99. 'rate' => 0.05,
  100. 'max' => 2000,
  101. 'min' => 200
  102. ],
  103. 'JT000' => [
  104. 'type' => 'sdjt',
  105. 'rate' => 0.08,
  106. 'max' => 300,
  107. 'min' => 100
  108. ],
  109. 'JT001' => [
  110. 'type' => 'sdjt',
  111. 'rate' => 0.08,
  112. 'max' => 3000,
  113. 'min' => 300
  114. ],
  115. 'JT002' => [
  116. 'type' => 'sdjt',
  117. 'rate' => 0.08,
  118. 'max' => 5000,
  119. 'min' => 500
  120. ],
  121. ];
  122. // 获取商户ID
  123. public static function getMerchantId()
  124. {
  125. return config('app.tree_pay_mch_id');
  126. }
  127. // 获取商户秘钥
  128. public static function getSecret()
  129. {
  130. return config('app.tree_pay_key');
  131. }
  132. // 获取异步的通知地址
  133. public static function getNotifyUrl()
  134. {
  135. $host = config('app.url');
  136. return $host.'/api/pay/harvest';
  137. }
  138. /**
  139. * @description: 获取请求客户端
  140. * @return {*}
  141. */
  142. public static function getClient(): Client
  143. {
  144. return new Client([
  145. 'base_uri' => self::REQUEST_URL,
  146. 'timeout' => 5.0,
  147. ]);
  148. }
  149. // 签名
  150. public static function signature($params = [],$must = [])
  151. {
  152. if($must){
  153. foreach($params as $k => $v){
  154. if(!in_array($k,$must)){
  155. unset($params[$k]);
  156. }
  157. }
  158. }
  159. ksort($params, SORT_STRING);
  160. $parts = [];
  161. foreach($params as $k => $v){
  162. array_push($parts,$k.'='.$v);
  163. }
  164. $mch_key = self::getSecret();
  165. $parts[] = "key=".$mch_key;
  166. $sign = md5(implode('&',$parts));
  167. return $sign;
  168. }
  169. /**
  170. * @description: 发起支付订单
  171. * @param {*} $amount 金额单位分
  172. * @param {*} $orderNo 订单号
  173. * @param {*} $type 支付通道
  174. * @return {*}
  175. */
  176. public static function pay($amount,$orderNo,$type = self::PRODUCT_TEST)
  177. {
  178. $must = ['mchId','productId','outTradeNo','amount','reqTime','notifyUrl'];
  179. $mch_id = self::getMerchantId();
  180. $data = [];
  181. $data['mchId'] = $mch_id;
  182. $data['amount'] = $amount;
  183. $data['outTradeNo'] = $orderNo;
  184. $data['notifyUrl'] = self::getNotifyUrl();
  185. $data['reqTime'] = time() * 1000;
  186. $data['productId'] = $type;
  187. $data['sign'] = self::signature($data,$must);
  188. $client = self::getClient();
  189. $response = $client->post('api/v1/pay/unifiedOrder', [
  190. 'json' => $data,
  191. 'headers' => [
  192. 'Content-Type' => 'application/json',
  193. ]
  194. ]);
  195. $body = $response->getBody();
  196. return json_decode($body->getContents(), true);
  197. }
  198. /**
  199. * @description: 查询订单
  200. * @param {*} $orderNo 订单号
  201. * @return {*}
  202. */
  203. public static function queryOrder($orderNo)
  204. {
  205. $must = ['mchId','outTradeNo','reqTime'];
  206. $mch_id = self::getMerchantId();
  207. $data = [];
  208. $data['mchId'] = $mch_id;
  209. $data['outTradeNo'] = $orderNo;
  210. $data['reqTime'] = time() * 1000;
  211. $data['sign'] = self::signature($data,$must);
  212. $client = self::getClient();
  213. $response = $client->post('api/v1/pay/queryOrder', [
  214. 'json' => $data,
  215. 'headers' => [
  216. 'Content-Type' => 'application/json',
  217. ]
  218. ]);
  219. $body = $response->getBody();
  220. return json_decode($body->getContents(), true);
  221. }
  222. }