2
0

PagYeepPay.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <?php
  2. namespace App\Services;
  3. use App\Util;
  4. class PagYeepPay
  5. {
  6. public $config;
  7. public $key;
  8. public $orgNo;
  9. public $custId;
  10. public $apiUrl;
  11. public function __construct()
  12. {
  13. $payConfigService = new PayConfig();
  14. $this->config = $payConfigService->getConfig('PagYeepPay');
  15. $this->key = $this->config['key'] ?? '';
  16. // $this->orgNo = $this->config['orgNo'] ?? '';
  17. // $this->custId = $this->config['custId'] ?? '';
  18. $this->apiUrl = $this->config['apiUrl'] ?? '';
  19. }
  20. /**
  21. * 签名 - PagYeepPay专用签名算法
  22. *
  23. * 规则(根据文档):
  24. * 1. 按参数名ASCII码从小到大排序(字典序)
  25. * 2. 空值不参与签名
  26. * 3. sign参数不参与签名
  27. * 4. 拼接格式:key1=value1&key2=value2&key=商户密钥
  28. * 5. 参数值使用原始值,不进行URL Encode
  29. * 6. MD5后转大写
  30. */
  31. public function sign(array $params): array
  32. {
  33. // 移除sign和空值
  34. $signParams = [];
  35. foreach ($params as $key => $value) {
  36. if ($key !== 'sign' && $value !== null && $value !== '') {
  37. $signParams[$key] = $value;
  38. }
  39. }
  40. // 按ASCII码排序
  41. ksort($signParams);
  42. // 拼接字符串:key1=value1&key2=value2(不进行URL Encode)
  43. $stringA = '';
  44. foreach ($signParams as $key => $value) {
  45. if ($stringA !== '') {
  46. $stringA .= '&';
  47. }
  48. $stringA .= $key . '=' . $value;
  49. }
  50. // 拼接商户密钥:stringA&key=商户密钥
  51. $stringSignTemp = $stringA . '&key=' . $this->key;
  52. // MD5并转大写
  53. $sign = strtoupper(md5($stringSignTemp));
  54. // 将签名添加到参数中
  55. $params['sign'] = $sign;
  56. Util::WriteLog('PagYeepPay_sign', "待签名字符串: " . $stringSignTemp);
  57. Util::WriteLog('PagYeepPay_sign', "签名结果: " . $sign);
  58. return $params;
  59. }
  60. /**
  61. * 验签 - PagYeepPay专用验签算法
  62. */
  63. public function verifySign(array $params): bool
  64. {
  65. if (!isset($params['sign'])) {
  66. return false;
  67. }
  68. $receivedSign = $params['sign'];
  69. // 移除sign和空值
  70. $signParams = [];
  71. foreach ($params as $key => $value) {
  72. if ($key !== 'sign' && $value !== null && $value !== '') {
  73. $signParams[$key] = $value;
  74. }
  75. }
  76. // 按ASCII码排序
  77. ksort($signParams);
  78. // 拼接字符串(不进行URL Encode)
  79. $stringA = '';
  80. foreach ($signParams as $key => $value) {
  81. if ($stringA !== '') {
  82. $stringA .= '&';
  83. }
  84. $stringA .= $key . '=' . $value;
  85. }
  86. // 拼接商户密钥
  87. $stringSignTemp = $stringA . '&key=' . $this->key;
  88. // MD5并转大写
  89. $calculatedSign = strtoupper(md5($stringSignTemp));
  90. Util::WriteLog('PagYeepPay_verify', "待验签字符串: " . $stringSignTemp);
  91. Util::WriteLog('PagYeepPay_verify', "计算签名: " . $calculatedSign);
  92. Util::WriteLog('PagYeepPay_verify', "接收签名: " . $receivedSign);
  93. return $calculatedSign === $receivedSign;
  94. }
  95. /**
  96. * POST请求 - application/x-www-form-urlencoded
  97. */
  98. public function curlPost($url, $payload)
  99. {
  100. $timeout = 20;
  101. // PagYeepPay使用 application/x-www-form-urlencoded 格式,UTF-8编码
  102. $data = http_build_query($payload, '', '&', PHP_QUERY_RFC3986);
  103. $headers = [
  104. 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
  105. ];
  106. $ch = curl_init();
  107. curl_setopt($ch, CURLOPT_URL, $url);
  108. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  109. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  110. curl_setopt($ch, CURLOPT_POST, 1);
  111. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  112. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
  113. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
  114. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  115. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  116. $result = curl_exec($ch);
  117. $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  118. if (curl_errno($ch)) {
  119. $error = curl_error($ch);
  120. Util::WriteLog('PagYeepPay_error', 'CURL Error: ' . $error);
  121. curl_close($ch);
  122. return false;
  123. }
  124. if ($httpCode != 200) {
  125. Util::WriteLog('PagYeepPay_error', 'HTTP Code: ' . $httpCode . " | Response: " . $result);
  126. }
  127. curl_close($ch);
  128. return $result;
  129. }
  130. }