From d3e81a1b00836566c698e9dd74875615e81f9ee5 Mon Sep 17 00:00:00 2001 From: ryosuke Date: Sat, 5 Mar 2022 22:31:52 +0800 Subject: [PATCH] add coinbase --- app/Payments/Coinbase.php | 129 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 app/Payments/Coinbase.php diff --git a/app/Payments/Coinbase.php b/app/Payments/Coinbase.php new file mode 100644 index 00000000..ed6fba33 --- /dev/null +++ b/app/Payments/Coinbase.php @@ -0,0 +1,129 @@ +config = $config; + } + + public function form() + { + return [ + 'coinbase_url' => [ + 'label' => '接口地址', + 'description' => '', + 'type' => 'input', + ], + 'coinbase_api_key' => [ + 'label' => 'API KEY', + 'description' => '', + 'type' => 'input', + ], + 'coinbase_webhook_key' => [ + 'label' => 'WEBHOOK KEY', + 'description' => '', + 'type' => 'input', + ], + ]; + } + + public function pay($order) { + + $params = [ + 'name' => '订阅套餐', + 'description' => '订单号 ' . $order['trade_no'], + 'pricing_type' => 'fixed_price', + 'local_price' => [ + 'amount' => sprintf('%.2f', $order['total_amount'] / 100), + 'currency' => 'CNY' + ], + 'metadata' => [ + "outTradeNo" => $order['trade_no'], + ], + ]; + + $params_string = http_build_query($params); + + $ret_raw = self::_curlPost($this->config['coinbase_url'], $params_string); + + $ret = @json_decode($ret_raw, true); + + if(empty($ret['data']['hosted_url'])) { + abort(500, "error!"); + } + return [ + 'type' => 1, + 'data' => $ret['data']['hosted_url'], + ]; + } + + public function notify($params) { + + $payload = trim(file_get_contents('php://input')); + $json_param = json_decode($payload, true); + + + $headerName = 'X-Cc-Webhook-Signature'; + $headers = getallheaders(); + $signatureHeader = isset($headers[$headerName]) ? $headers[$headerName] : ''; + $computedSignature = \hash_hmac('sha256', $payload, $this->config['coinbase_webhook_key']); + + if (!self::hashEqual($signatureHeader, $computedSignature)) { + abort(400, 'HMAC signature does not match'); + } + + $out_trade_no = $json_param['event']['data']['metadata']['outTradeNo']; + $pay_trade_no=$json_param['event']['id']; + return [ + 'trade_no' => $out_trade_no, + 'callback_no' => $pay_trade_no + ]; + http_response_code(200); + die('success'); + } + + + private function _curlPost($url,$params=false){ + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 300); + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + curl_setopt( + $ch, CURLOPT_HTTPHEADER, array('X-CC-Api-Key:' .$this->config['coinbase_api_key'], 'X-CC-Version: 2018-03-22') + ); + $result = curl_exec($ch); + curl_close($ch); + return $result; + } + + + /** + * @param string $str1 + * @param string $str2 + * @return bool + */ + public function hashEqual($str1, $str2) + { + if (function_exists('hash_equals')) { + return \hash_equals($str1, $str2); + } + + if (strlen($str1) != strlen($str2)) { + return false; + } else { + $res = $str1 ^ $str2; + $ret = 0; + + for ($i = strlen($res) - 1; $i >= 0; $i--) { + $ret |= ord($res[$i]); + } + return !$ret; + } + } + +} +