Pay.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. namespace app\extra\dyMini;
  3. use app\extra\dyLife\BasicLife;
  4. use yzh52521\EasyHttp\Http;
  5. class Pay extends BasicLife
  6. {
  7. public function createOrder(array $data = [])
  8. {
  9. $url = "https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
  10. $param = [
  11. "out_order_no" => $data['order_sn'].rand(1000,9999),
  12. "total_amount" => (int) $data['total'],
  13. "subject" => $data['name'],
  14. "body" => $data['name'],
  15. "valid_time" => 1800,
  16. "notify_url" => $data['notify_url'],
  17. "cp_extra" => $data['order_sn']
  18. ];
  19. $param['sign'] = $this->requestSign($param);
  20. $param['app_id'] = $this->config['appid'];
  21. $resp = Http::asJson()->post($url,$param)->array();
  22. if ($resp['err_no'] == 0) {
  23. return $resp['data'];
  24. }
  25. return [];
  26. }
  27. public function createRefund(array $data = [])
  28. {
  29. $url = "https://developer.toutiao.com/api/apps/ecpay/v1/create_refund";
  30. $param = [
  31. "out_order_no" => $data['out_refund_no'],
  32. "out_refund_no" => $data['out_refund_no'],
  33. // "out_refund_no" => $data['order_sn'].rand(1000,9999),
  34. "refund_amount" => (int) $data['total'],
  35. "reason" => $data['reason'],
  36. "notify_url" => $data['notify_url'],
  37. "cp_extra" => $data['order_sn']
  38. ];
  39. $param['sign'] = $this->requestSign($param);
  40. $param['app_id'] = $this->config['appid'];
  41. $resp = Http::asJson()->post($url,$param)->array();
  42. if ($resp['err_no'] == 0) return true;
  43. return false;
  44. }
  45. /**
  46. * 生成签名
  47. */
  48. private function requestSign($params): string
  49. {
  50. $rList = [];
  51. foreach($params as $k =>$v) {
  52. if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
  53. continue;
  54. $value = trim(strval($v));
  55. if (is_array($v)) {
  56. $value = arrayToStr($v);
  57. }
  58. $len = strlen($value);
  59. if ($len > 1 && substr($value, 0,1)=="\"" && substr($value, $len-1)=="\"")
  60. $value = substr($value,1, $len-1);
  61. $value = trim($value);
  62. if ($value == "" || $value == "null")
  63. continue;
  64. $rList[] = $value;
  65. }
  66. $rList[] = $this->config['salt'];
  67. sort($rList, SORT_STRING);
  68. return md5(implode('&', $rList));
  69. }
  70. /**
  71. * @param $privateKeyStr
  72. * @param $data
  73. * @param $appId
  74. * @param $nonceStr
  75. * @param $timestamp
  76. * @param $keyVersion
  77. * @return string|null
  78. * @throws \Exception
  79. */
  80. public function getByteAuthorization(string $privateKeyStr, string $data, string $appId, string $nonceStr,string $timestamp, string $keyVersion) {
  81. $byteAuthorization = '';
  82. // 读取私钥
  83. $privateKey = openssl_pkey_get_private($privateKeyStr);
  84. if (!$privateKey) {
  85. throw new \Exception("Invalid private key");
  86. }
  87. // 生成签名
  88. $signature = $this->getSignature("POST", "/requestOrder", $timestamp, $nonceStr, $data, $privateKeyStr);
  89. if ($signature === false) {
  90. return null;
  91. }
  92. // 构造 byteAuthorization
  93. $byteAuthorization = sprintf("SHA256-RSA2048 appid=%s,nonce_str=%s,timestamp=%s,key_version=%s,signature=%s", $appId, $nonceStr, $timestamp, $keyVersion, $signature);
  94. return $byteAuthorization;
  95. }
  96. public function getSignature(string $method, string $url, string $timestamp, string $nonce, $data, $privateKey) {
  97. // printf("method:%s\n url:%s\n timestamp:%s\n nonce:%s\n data:%s", $method, $url, $timestamp, $nonce, $data);
  98. $targetStr = $method. "\n" . $url. "\n" . $timestamp. "\n" . $nonce. "\n" . $data. "\n";
  99. openssl_sign($targetStr, $sign, $privateKey, OPENSSL_ALGO_SHA256);
  100. return base64_encode($sign);
  101. }
  102. }