PayUtil.php 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace app\utils;
  3. class PayUtil
  4. {
  5. private $message = '';
  6. private $data = [];
  7. private $config = [
  8. 'sub_appid' => 'wx29d6281c5252f504',
  9. 'huifu_id' => '6666000145960408',
  10. 'sys_id' => '6666000145960408',
  11. 'product_id' => 'YMFZS',
  12. 'rsaPrivateKey' => 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCWjQ+o6u8TgOQETBJs/OebvIZMLZ7J0kyAfyKXECl44R2EvfOWTNhtnDc6ZuaXegBoNo8u+skVxzy8k+unoBNghpct/BCaXc2op0F/3/3kc+Y5I74PX2lF//4MvCNP1ia+ykfHJkdnlfz2W8c2Tc1L311PPQ4dsB0c6mup/NjV1DX0WkAXWsMCHSss1iRLLb5mqVJtCkSbPmuSZV+bm+JASsD5goo32245HxqNbjKm/fi+OfZ9ONKl0wT+Ch5SQEbQAr61yhIyHdlqc7o7xupbYFKjT4ez8Y3VU4U1uKu57x2cKI0ETwsASALDqgvYS6mFjJFC3LcEjskyAAi1a+HNAgMBAAECggEABvS1iIRyT2BhKKGrKEX3HYb0XYiuEX0Z88Xr/zbL873S81MjcgpS5Z2WH6ipds44PphmvTDxIYR3Fe9vr+sBejA9w+4lhjxXSDeSGypqPKfuNy2jlmo+HvHY9xWqPAIVADOwZU8rdWnEqk1LQwMNPTgww3x6rnx4m+Fo4A3Cpv54vrK7f4fTUaaD8gHRFkSkkCvNJYEZdd5OLqCKwuAwL6vxwhX/tBuNa+zltw+9fV+FCnaBlkVncU8j8os7FBoT7MTbMoijDG78b1feUofuWUmn4A+lb/hH9R2zTNaTlGzTdyj/hybkPmz3TMPsymzIxpr239z8HZvVfnBiScFUAQKBgQDhj/mGKM7tkYuR+gRgBwlvtsPyru3DmaqabkweBz6nL9c7F5bVrLuoSZRkZTEfwU/lHDpRPqP6elLdv7NQvPt6deXZIt+LqXHcFr8k/l0xhT4EaUcYjVyj0rVfLrjM8y4yVruDEJm9d3PjYoe4vF2+TSZ3gXqwEOCflVB2Xk9eDQKBgQCq3dPb5Xj+O/8IaiGnLP/iED7hJ27EupR9MbvNS760e03dTHePKnfoeVJve06cx380RLM2mEicFUz7ee1+Kvu/79v4OabBn9WDDFMME0nb52FyRDf9jkG6jB2bKP8olVhufCvhsjxJXXCNepAZwi3m4CgWz5km3AMe77f276liwQKBgGkY9GKWURRQZH+3xqIXpUXwGozRBOfGib869Sxoo8Cygc5+x0D4ItfesM22eJUbNWbDKEkCrtTeeg3obFyKMYJ1vIrXvOEOKocp8hYCjtmsA6F6jC3cb/XFD80xr9mO1U+PKf9/lKK7LbwdBLAG1Ib+25WDNu8ibgbtQ3hjqQdhAoGBAJMHcyjDm4vZgKly+iZq2H1k0VbZob1zeBcK1rnfteiEOgp1pGPzfV70FvWLO6g5GsKVY0lVXRXCVo4G61AoGJ2e/r/ojBANQ6MS1duMNYAe6IF1JmDvKqwlqcw8SORZLtFT1EbQIoRW/WUg1CL2Lp1+wcBvPzBrHdxfFwRMUouBAoGBAKusKZFR5bqj5NDb3Uli3D0H48PxTOq5iNvkG9L/wUfUTV1p1e0bnQ+ViEmh6LdLEuvVnClDTFuyaxFe3mp0lREcPYsdk4sYXkBvTO5B7CkoVtoNLPZxfYEDRkDbCQ9LniE155qP0ikEhf4pQRB2RNuC0DfO2O5uoYXdp+uFiuNt',
  13. 'rsaPublicKey' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlo0PqOrvE4DkBEwSbPznm7yGTC2eydJMgH8ilxApeOEdhL3zlkzYbZw3Ombml3oAaDaPLvrJFcc8vJPrp6ATYIaXLfwQml3NqKdBf9/95HPmOSO+D19pRf/+DLwjT9YmvspHxyZHZ5X89lvHNk3NS99dTz0OHbAdHOprqfzY1dQ19FpAF1rDAh0rLNYkSy2+ZqlSbQpEmz5rkmVfm5viQErA+YKKN9tuOR8ajW4ypv34vjn2fTjSpdME/goeUkBG0AK+tcoSMh3ZanO6O8bqW2BSo0+Hs/GN1VOFNbirue8dnCiNBE8LAEgCw6oL2EuphYyRQty3BI7JMgAItWvhzQIDAQAB',
  14. 'huiRsaPublicKey' => "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkA7CU0t1vIlnRC8vT2pD2CiSUb5KpVI2lOzHaNlxAQyFRfTfe4xAFw2XMxYvv4f2jgWlQwYTC13+m9aboQglzJtw7VXtw4G8I5DEDnYOiU2Z2vC/TaRFw3OLICk7H8WuWKN6Rn2iiVsauh+Jy31G9MOlUbFbIQjfw1J0NIbscbUsvCwUrc1DG3onM1aFTyFjTTmLYw7SjCkX7T4SKaBfP6Nqn87d8fkrcP6ruXHt4Zmf6xAFcTBuwpw9FRjzHn4bpxDatFleO9KFqHoBTDe0EGWHWhmShG7Mn1ubAGWJ/OUe9CLEOKVSnNYtR7MFlhoO+DmYlz5iSy7lYWmS6sTpGwIDAQAB",
  15. ];
  16. public function __construct()
  17. {
  18. }
  19. public function jsPay(string $openid, string $order_no, string $amount, string $desc = '', string $notify_url = '', string $type = 'T_MINIAPP')
  20. {
  21. $url = "https://api.huifu.com/v2/trade/payment/jspay";
  22. $post_data = [
  23. 'req_date' => date('Ymd'),
  24. 'req_seq_id' => $order_no,//请求流水号 示例值:rQ2021121311173944134649875651
  25. 'huifu_id' => $this->config['huifu_id'],//渠道与一级代理商的直属商户ID;示例值:6666000123123123
  26. 'goods_desc' => $desc,//商品描述
  27. //交易类型T_JSAPI: 微信公众号;T_MINIAPP: 微信小程序;A_JSAPI: 支付宝JS;A_NATIVE: 支付宝正扫;U_NATIVE: 银联正扫
  28. // U_JSAPI: 银联JS;D_NATIVE: 数字人民币正扫;T_H5:微信直连H5支付;T_APP:微信APP支付(只支持直连);T_NATIVE:微信正扫(只支持直连);示例值:A_NATIVE
  29. 'trade_type' => $type,
  30. 'trans_amt' => $amount,// 交易金额 单位元 最低传入0.01
  31. 'wx_data' => [
  32. 'sub_appid' => $this->config['sub_appid'],
  33. 'sub_openid' => $openid,
  34. ],
  35. 'notify_url' => $notify_url
  36. ];
  37. // ksort($post_data);
  38. $data = [
  39. 'sys_id' => $this->config['sys_id'],
  40. 'product_id' => $this->config['product_id'],
  41. 'sign' => $this->getSign($post_data),
  42. 'data' => $post_data
  43. ];
  44. $res = CurlUtil::postJson($url, $data);
  45. if (empty($res['data']['resp_code']) || $res['data']['resp_code'] != '00000100') {
  46. return $this->error($res['data']['resp_desc'] ?? '下单失败', $res);
  47. }
  48. return $this->success($res['data']['resp_desc'] ?? '下单成功!', $res);
  49. }
  50. private function getSign($post_data)
  51. {
  52. ksort($post_data);
  53. $post_data = json_encode($post_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
  54. return $this->sha_with_rsa_sign($post_data, $this->config['rsaPrivateKey']);
  55. }
  56. public function checkSign($signature, $data)
  57. {
  58. return $this->verifySign($signature,$data,$this->config['huiRsaPublicKey']);
  59. }
  60. /**
  61. * 私钥加签(对数据源排序),可用于 V2 版本接口数据加签
  62. *
  63. * @param string $data 原数据( 排序后的json字符串; 数组参数排序后转json字符串(数据的中文和斜杠均不转码):ksort($post_data); json_encode($post_data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); )
  64. * @param string $rsaPrivateKey 私钥
  65. * @param int $alg 默认 OPENSSL_ALGO_SHA256
  66. * @return false|string 签名串
  67. */
  68. private function sha_with_rsa_sign(string $data, string $rsaPrivateKey, int $alg = OPENSSL_ALGO_SHA256)
  69. {
  70. $key = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($rsaPrivateKey, 64, "\n", true) . "\n-----END PRIVATE KEY-----";
  71. $signature = '';
  72. try {
  73. openssl_sign($data, $signature, $key, $alg);
  74. return base64_encode($signature);
  75. } catch (\Exception $e) {
  76. $this->message = $e->getMessage();
  77. return false;
  78. }
  79. }
  80. /**
  81. * 使用公钥验签,可用于异步应答验签
  82. *
  83. * @param string $signature 签文
  84. * @param string $data 原数据(string)
  85. * @param string $rsaPublicKey 公钥
  86. * @param int $alg 默认 OPENSSL_ALGO_SHA256
  87. *
  88. * @return false|int 验证结果:成功/失败
  89. */
  90. public static function verifySign($signature, $data, $rsaPublicKey, $alg=OPENSSL_ALGO_SHA256){
  91. $key = "-----BEGIN PUBLIC KEY-----\n".wordwrap($rsaPublicKey, 64, "\n", true)."\n-----END PUBLIC KEY-----";
  92. return openssl_verify($data, base64_decode($signature), $key, $alg);
  93. }
  94. private function success($message = '', $data = [])
  95. {
  96. $this->message = $message;
  97. $this->data = $data;
  98. return true;
  99. }
  100. private function error($message = '', $data = [])
  101. {
  102. $this->message = $message;
  103. $this->data = $data;
  104. return false;
  105. }
  106. public function getMessage()
  107. {
  108. return $this->message;
  109. }
  110. public function getData()
  111. {
  112. return $this->data;
  113. }
  114. }