PasspayClient.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. namespace app\utils\JingXiu;
  3. use app\utils\CurlUtil;
  4. class PasspayClient
  5. {
  6. //接口地址
  7. private $apiurl;
  8. //商户号
  9. private $mchid;
  10. //商户私钥
  11. private $merchant_private_key;
  12. //平台公钥
  13. private $platform_public_key;
  14. private $charset = 'utf-8';
  15. private $sign_type = 'RSA2';
  16. private $version = '1.0';
  17. public function __construct($apiurl, $mchid, $merchant_private_key, $platform_public_key)
  18. {
  19. $this->apiurl = $apiurl;
  20. $this->mchid = $mchid;
  21. $this->merchant_private_key = $merchant_private_key;
  22. $this->platform_public_key = $platform_public_key;
  23. }
  24. //请求API接口并解析返回数据
  25. public function execute($method, $bizContent)
  26. {
  27. $requrl = $this->apiurl . $method;
  28. $params = [
  29. 'mchid' => $this->mchid,
  30. 'method' => $method,
  31. 'charset' => $this->charset,
  32. 'sign_type' => $this->sign_type,
  33. 'timestamp' => time(),
  34. 'version' => $this->version,
  35. 'biz_content' => json_encode($bizContent)
  36. ];
  37. $params['sign'] = $this->generateSign($params);
  38. $response = CurlUtil::postJson($requrl,$params);
  39. if (isset($response['code']) && $response['code'] == 1) {
  40. return $response['data'];
  41. } elseif (isset($response['msg'])) {
  42. throw new \Exception($response['msg']);
  43. } else {
  44. throw new \Exception('返回数据解析失败');
  45. }
  46. }
  47. //获取待签名字符串
  48. private function getSignContent($param)
  49. {
  50. ksort($param);
  51. $signstr = '';
  52. foreach ($param as $k => $v) {
  53. if ($k != "sign" && $v !== '' && $v !== null) {
  54. $signstr .= $k . '=' . $v . '&';
  55. }
  56. }
  57. $signstr = substr($signstr, 0, -1);
  58. return $signstr;
  59. }
  60. //请求参数签名
  61. private function generateSign($param)
  62. {
  63. return $this->rsaPrivateSign($this->getSignContent($param));
  64. }
  65. //验签方法
  66. public function verifySign($param)
  67. {
  68. if (empty($param['sign'])) return false;
  69. return $this->rsaPubilcSign($this->getSignContent($param), $param['sign']);
  70. }
  71. //商户私钥签名
  72. private function rsaPrivateSign($data)
  73. {
  74. $priKey = $this->merchant_private_key;
  75. $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
  76. wordwrap($priKey, 64, "\n", true) .
  77. "\n-----END RSA PRIVATE KEY-----";
  78. $pkeyid = openssl_pkey_get_private($res);
  79. if (!$pkeyid) {
  80. throw new Exception('签名失败,商户私钥不正确');
  81. }
  82. openssl_sign($data, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
  83. $signature = base64_encode($signature);
  84. return $signature;
  85. }
  86. /**
  87. * 平台公钥验签
  88. * @param $data
  89. * @param $signature
  90. * @return bool
  91. */
  92. private function rsaPubilcSign($data, $signature)
  93. {
  94. $pubKey = $this->platform_public_key;
  95. $res = "-----BEGIN PUBLIC KEY-----\n" .
  96. wordwrap($pubKey, 64, "\n", true) .
  97. "\n-----END PUBLIC KEY-----";
  98. $pubkeyid = openssl_pkey_get_public($res);
  99. if (!$pubkeyid) {
  100. throw new Exception('验签失败,平台公钥不正确');
  101. }
  102. $result = openssl_verify($data, base64_decode($signature), $pubkeyid, OPENSSL_ALGO_SHA256);
  103. return $result === 1;
  104. }
  105. }