PayStack.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. namespace common\helpers;
  3. class PayStack
  4. {
  5. public static function verifyWebhookSignature(string $rawBody, string $signature, string $secretKey): bool
  6. {
  7. return $signature !== '' && hash_equals(hash_hmac('sha512', $rawBody, $secretKey), $signature);
  8. }
  9. /**
  10. * 根据运行环境加载secretKey
  11. */
  12. public static function getSecretKey(): string
  13. {
  14. return YII_ENV == YII_ENV_PROD ? \Yii::$app->Paystack->liveSecretKey : \Yii::$app->Paystack->testSecretKey;
  15. // return \Yii::$app->Paystack->testSecretKey;
  16. }
  17. /**
  18. * 支付.
  19. */
  20. public static function transactionInit($currency, $amount, $email, array $metadata = [], string $reference = '')
  21. {
  22. $secretKey = self::getSecretKey();
  23. LoggerTool::info('env: ' . YII_ENV);
  24. if (YII_ENV != YII_ENV_PROD) {
  25. if ($reference === '') {
  26. $reference = bin2hex(random_bytes(16));
  27. }
  28. return [
  29. 'status' => true,
  30. 'data' => [
  31. 'amount' => (int) round($amount * 100),
  32. 'currency' => strtoupper((string) $currency),
  33. 'reference' => $reference,
  34. 'authorization_url' => 'https://checkout.paystack.com/' . $reference,
  35. 'access_code' => $reference,
  36. ]
  37. ];
  38. }
  39. try {
  40. $url = "https://api.paystack.co/transaction/initialize";
  41. $fields = [
  42. 'email' => $email,
  43. 'amount' => (int) round($amount * 100),
  44. 'currency' => strtoupper((string) $currency),
  45. ];
  46. if ($reference !== '') {
  47. $fields['reference'] = $reference;
  48. }
  49. if ($metadata) {
  50. $fields['metadata'] = json_encode($metadata, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  51. }
  52. $fields_string = http_build_query($fields);
  53. //open connection
  54. $curl = curl_init();
  55. //set the url, number of POST vars, POST data
  56. curl_setopt($curl,CURLOPT_URL, $url);
  57. curl_setopt($curl,CURLOPT_POST, true);
  58. curl_setopt($curl,CURLOPT_POSTFIELDS, $fields_string);
  59. curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  60. "Authorization: Bearer {$secretKey}",
  61. "Cache-Control: no-cache",
  62. ));
  63. //So that curl_exec returns the contents of the cURL; rather than echoing it
  64. curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
  65. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
  66. curl_setopt($curl, CURLOPT_TIMEOUT, 30);
  67. //execute post
  68. $result = curl_exec($curl);
  69. $err = curl_error($curl);
  70. curl_close($curl);
  71. if ($err) {
  72. return [
  73. 'status' => false,
  74. 'message' => $err,
  75. ];
  76. }
  77. return json_decode($result, true);
  78. } catch (\Exception $e) {
  79. return [
  80. 'status' => false,
  81. 'message' => $e->getMessage(),
  82. ];
  83. }
  84. }
  85. /**
  86. * 交易结果校验.
  87. * @param $ref
  88. * @return array
  89. */
  90. public static function transactionVerify($ref): array
  91. {
  92. $secretKey = self::getSecretKey();
  93. try {
  94. $curl = curl_init();
  95. curl_setopt_array($curl, [
  96. CURLOPT_URL => "https://api.paystack.co/transaction/verify/{$ref}",
  97. CURLOPT_RETURNTRANSFER => true,
  98. CURLOPT_ENCODING => "",
  99. CURLOPT_MAXREDIRS => 10,
  100. CURLOPT_TIMEOUT => 30,
  101. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  102. CURLOPT_CUSTOMREQUEST => "GET",
  103. CURLOPT_HTTPHEADER => array(
  104. "Authorization: Bearer {$secretKey}",
  105. "Cache-Control: no-cache",
  106. ),
  107. ]);
  108. $response = curl_exec($curl);
  109. $err = curl_error($curl);
  110. curl_close($curl);
  111. if ($err) {
  112. return [
  113. 'status' => false,
  114. 'message' => $err,
  115. ];
  116. }
  117. return json_decode($response, true);
  118. } catch (\Exception $e) {
  119. return [
  120. 'status' => false,
  121. 'message' => $e->getMessage(),
  122. ];
  123. }
  124. }
  125. /**
  126. * 交易退款.
  127. * @param string $reference
  128. * @param int $amount
  129. * @return array
  130. */
  131. public static function transactionRefund(string $reference, int $amount)
  132. {
  133. $secretKey = self::getSecretKey();
  134. try {
  135. $url = "https://api.paystack.co/refund";
  136. $fields = [
  137. 'transaction' => $reference,
  138. 'amount' => $amount,
  139. ];
  140. $fields_string = http_build_query($fields);
  141. //open connection
  142. $curl = curl_init();
  143. //set the url, number of POST vars, POST data
  144. curl_setopt($curl, CURLOPT_URL, $url);
  145. curl_setopt($curl, CURLOPT_POST, true);
  146. curl_setopt($curl, CURLOPT_POSTFIELDS, $fields_string);
  147. curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  148. "Authorization: Bearer {$secretKey}",
  149. "Cache-Control: no-cache",
  150. ));
  151. //So that curl_exec returns the contents of the cURL; rather than echoing it
  152. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  153. //execute post
  154. $response = curl_exec($curl);
  155. $err = curl_error($curl);
  156. curl_close($curl);
  157. if ($err) {
  158. return [
  159. 'status' => false,
  160. 'message' => $err,
  161. ];
  162. }
  163. return json_decode($response, true);
  164. } catch (\Exception $e) {
  165. return [
  166. 'status' => false,
  167. 'message' => $e->getMessage(),
  168. ];
  169. }
  170. }
  171. }