PayUtils.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php
  2. namespace common\pay\huayin;
  3. class PayUtils
  4. {
  5. /**
  6. *功能:华银个人网银支付接口
  7. *版本:3.0
  8. *日期:2017-06-30
  9. *说明:
  10. *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,
  11. *并非一定要使用该代码。该代码仅供学习和研究华银接口使用,仅为提供一个参考。
  12. * @param array $data
  13. * @param $merchant_private_key
  14. * @return string
  15. */
  16. public static function makeSign($data, $merchant_private_key)
  17. {
  18. /////////////////////////// 初始化接口参数 //////////////////////////////
  19. /**
  20. * 接口参数请参考华银网银支付文档,除了sign参数,其他参数都要在这里初始化
  21. */
  22. ///////////////////////////// 参数组装 /////////////////////////////////
  23. /**
  24. * 除了sign_type参数,其他非空参数都要参与组装,组装顺序是按照a~z的顺序,下划线"_"优先于字母
  25. */
  26. $signStr = "";
  27. ksort($data);
  28. foreach ($data as $key => $value) {
  29. if ($key == "sign" || $key == "sign_type" || $value === null || $value === "") {
  30. continue;
  31. }
  32. $value = strval($value);
  33. $signStr .= "{$key}={$value}&";
  34. }
  35. $signStr = rtrim($signStr, '&');
  36. ///////////////////////////// 获取sign值(RSA-S加密) /////////////////////////////////
  37. if (strpos($merchant_private_key, "file://") === false) {
  38. if (strpos($merchant_private_key, "-----BEGIN PRIVATE KEY-----") === false) {
  39. $merchant_private_key_lines = [];
  40. $merchant_private_key_lines[] = "-----BEGIN PRIVATE KEY-----";
  41. for ($index = 0, $len = strlen($merchant_private_key); $index < $len; $index += 64) {
  42. $merchant_private_key_lines[] = substr($merchant_private_key, $index, 64);
  43. }
  44. $merchant_private_key_lines[] = "-----END PRIVATE KEY-----";
  45. $merchant_private_key = implode("\n", $merchant_private_key_lines);
  46. }
  47. }
  48. $merchant_private_key = openssl_get_privatekey($merchant_private_key);
  49. openssl_sign($signStr, $sign_info, $merchant_private_key, OPENSSL_ALGO_MD5);
  50. $sign = base64_encode($sign_info);
  51. return $sign;
  52. }
  53. /**
  54. *功能:华银个人网银支付异步通知接口
  55. *版本:3.0
  56. *日期:2017-06-30
  57. *说明:
  58. *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,
  59. *并非一定要使用该代码。该代码仅供学习和研究华银接口使用,仅为提供一个参考。
  60. */
  61. public static function checkSign($data, $dinpay_public_key)
  62. {
  63. ////////////////////////// 接收华银返回通知数据 /////////////////////////////////
  64. /**
  65. * 获取订单支付成功之后,华银通知服务器以post方式返回来的订单通知数据,参数详情请看接口文档,
  66. */
  67. ///////////////////////////// 参数组装 /////////////////////////////////
  68. /**
  69. * 除了sign_type dinpaySign参数,其他非空参数都要参与组装,组装顺序是按照a~z的顺序,下划线"_"优先于字母
  70. */
  71. $dinpaySign = isset($data["sign"]) ? base64_decode($data["sign"]) : "";
  72. if (isset($data['order_amount'])) {
  73. $data['order_amount'] = number_format($data['order_amount'], 2, '.', '');
  74. }
  75. $signStr = "";
  76. ksort($data);
  77. foreach ($data as $key => $value) {
  78. if ($key == "sign" || $key == "sign_type" || $value === null || $value === "") {
  79. continue;
  80. }
  81. $value = strval($value);
  82. $signStr .= "{$key}={$value}&";
  83. }
  84. $signStr = rtrim($signStr, '&');
  85. ///////////////////////////// RSA-S验证 /////////////////////////////////
  86. if (strpos($dinpay_public_key, "file://") === false) {
  87. if (strpos($dinpay_public_key, "-----BEGIN PUBLIC KEY-----") === false) {
  88. $dinpay_public_key_lines = [];
  89. $dinpay_public_key_lines[] = "-----BEGIN PUBLIC KEY-----";
  90. for ($index = 0, $len = strlen($dinpay_public_key); $index < $len; $index += 64) {
  91. $dinpay_public_key_lines[] = substr($dinpay_public_key, $index, 64);
  92. }
  93. $dinpay_public_key_lines[] = "-----END PUBLIC KEY-----";
  94. $dinpay_public_key = implode("\n", $dinpay_public_key_lines);
  95. }
  96. }
  97. $dinpay_public_key = openssl_get_publickey($dinpay_public_key);
  98. $flag = openssl_verify($signStr, $dinpaySign, $dinpay_public_key, OPENSSL_ALGO_MD5);
  99. /////////////////////////// 响应“SUCCESS” /////////////////////////////
  100. if ($flag) {
  101. return true;
  102. } else {
  103. return false;
  104. }
  105. }
  106. }