| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- <?php
- namespace app\api\complex;
- use think\Exception;
- /**
- * 快手
- */
- class Kuaishou implements ComplexInterface
- {
- private $channel = 'jcyx';
- private $open_url = "https://open.kuaishou.com/";
- private $pay_url = "https://allin.kuaishoupay.com/";
- private $qmPrivateKey = ''; // 祈盟公钥
- private $ksPublicKey = ''; // 快手私钥
- // 渠道效验
- public function getSpecialParam($data,$polyChannelGame = []){
- if (!$paramArr = json_decode($polyChannelGame['param'], true)) {
- return false;
- }
- $param = [
- 'app_id' => $paramArr['app_id'],
- 'game_id' => $data['user_id'],
- 'game_token' => $data['channel_token'],
- ];
- $result = getHttpGet($this->open_url . 'game/user_info/v2', $param);
- $res = json_decode($result, true);
- if ($res['result'] == 1) {
- return $data['user_id'];
- } else {
- return false;
- }
- }
-
- // 登陆效验
- public function checkLogin($data, $polyChannelGame = [])
- {
- return ['user_id' => $data['user_id']];
- }
- // ## 下单
- public function getOrder($data)
- {
- if (!$channelConfig = json_decode($data['channel_info']['param'], true)) {
- return false;
- }
- if(empty($data['extparam']) || empty($data['extparam']['user_id']) || empty($data['extparam']['channel_id'])){
- return ['code' => -200, 'msg' => '登录失效,请重新登录!', 'param' => []];
- }
- $requiredKeys = ['roleid', 'rolename', 'rolelevel', 'serverid', 'server_name', 'product_id', 'amount', 'notify_url'];
- $missingKeys = checkDataHasKeys($data, $requiredKeys);
- if (!empty($missingKeys)) {
- return ['code' => -200, 'msg' => '缺失参数:' . implode(', ', $missingKeys), 'param' => []];
- }
- try {
- $param = [
- "app_id" => $channelConfig['app_id'],
- "channel_id" => $data['extparam']['channel_id'],
- "game_id" => $data['extparam']['user_id'],
- "role_id" => $data['roleid'],
- "role_name" => $data['rolename'],
- "role_level" => $data['rolelevel'],
- "server_id" => $data['serverid'],
- "server_name" => $data['server_name'],
- "product_id" => $data['product_id'],
- "product_name" => $data['product_name']??'',
- "product_desc" => $data['product_desc']??'',
- "money" => formatYuanToFen($data['amount']),
- "currency_type" => 'CNY',
- "notify_url" => $data['notify_url'],
- "extension" => json_encode(['order_id' => $data['pay_info']['orderid']]),
- "user_ip" => $data['pay_info']['ip'],
- "third_party_trade_no" => $data['pay_info']['orderid'],
- ];
- $param['sign'] = $this->handleSIgn($param, $this->getKeyData('pay'));
- }catch (Exception $e){
- return ['code' => -200, 'msg' => $e->getMessage()];
- }
- return ['code' => 200, 'msg' => 'success', 'param' => $param];
- }
-
- // 回调订单参数
- public function getData($data)
- {
- $orderData = json_decode($data['extension'], true);
- if(empty($orderData['order_id'])){
- return false;
- }
- return [
- 'orderid' => $orderData['order_id'],//我方聚合订单
- 'amount' => formatFenToYuan($data['money']), // 充值金额(单位:元)
- 'sub_orderid' => $data['allin_trade_no'],//渠道订单
- ];
- }
- // 回调效验
- public function paySign($data, $polyChannelGame = [])
- {
- // 回调范例:{"app_id":"ks684828619578671316","role_id":"202005201314","server_id":"1","product_id":"kdzz_goods_001","money":"1","extension":"{\"order_id\":\"CMWL17452303393425188518\"}","allin_trade_no":"AI677228795252780746","data":"{\"environment\":\"PRODUCTION\"}","sign":"k0SSvITO06zSsC74nwWnePYe0cFyoneAlYeMGDSDx9ZZr4Lqal\/LWFRRMQbL1hxhQ4VcUpOyqpY+B5h7U1KsgO0gh\/6VQDK0ZbMrxP8RnGnalo5ua1d+FkiIYMcSlx\/5848XAC4GbHRCLUClAE+IQ4B4s6djxv5Usujvma\/4gIwW53TWJrbU+F3Pzi0G9arMoRFkl9fqgO1nEtSDeX8oZH1+cOHFoONIkZXa4z+Y7sErC0FuJHOKQSznzSa5iAcgEXqG1cfCvLo0nVRDoyJ\/AIb36GEerHzK0RomXd+5LrHyf\/zyE4VJzpgh\/JaslcSC7vQUf7MrqmJqDnHSHSCE4w=="}
- try {
- $requiredKeys = ['app_id', 'role_id', 'server_id', 'product_id', 'money', 'extension', 'allin_trade_no', 'sign'];
- $missingKeys = checkDataHasKeys($data, $requiredKeys);
- if (!empty($missingKeys)) {
- return "ERROR: 回调参数不匹配!";
- }
- $param = [
- 'app_id' => $data['app_id'],
- 'role_id' => $data['role_id'],
- 'server_id' => $data['server_id'],
- 'product_id' => $data['product_id'],
- 'money' => $data['money'],
- 'extension' => $data['extension'],
- 'allin_trade_no' => $data['allin_trade_no'],
- 'data' => $data['data']??'',
- 'notify_detail' => $data['notify_detail']??'',
- 'sign' => $data['sign'],
- ];
- $result = $this->handleSignVerify($param, $this->getKeyData('notify'), $param['sign']);
- if ($result) {
- return true;
- }
- } catch (Exception $e){
- return "ERROR: ".$e->getMessage();
- }
- return false;
- }
- public function getFail($msg = '')
- {
- echo 'fail:'.$msg;
- exit();
- }
- public function getSuccess($msg = '')
- {
- echo 'success';
- exit();
- }
- /**
- * 设置需要存储的数据
- *
- * @param $input 请求参数
- * @return array
- */
- public function setParam($input){
- if($input == '' || is_null($input)) return "";
- return [
- "user_id" => $input['user_id'],
- "channel_id" => $input['extparam'],
- ];
- }
- /**
- * 获取签名秘钥
- *
- * @param $type 类型 pay|notify
- * @return string
- */
- public function getKeyData($type = 'pay')
- {
- $key_file = APP_PATH . 'common/config/complex/qm_private_key.pem';
- if ($type == 'notify') {
- $key_file = APP_PATH . 'common/config/complex/kuaishou_public.pem';
- }
- if (!file_exists($key_file)) {
- throw new Exception('签名秘钥文件不存在');
- }
- return file_get_contents($key_file);
- }
- /**
- * 处理签名数据
- *
- * @param $data
- *
- * @return string
- */
- public function handleSignData($data){
- ksort($data);
- $signString = '';
- foreach ($data as $key => $value) {
- if($key == 'sign' || $value == ''){
- continue;
- }
- if ($signString !== '') {
- $signString .= '&';
- }
- $signString .= $key . '=' . $value;
- }
- return $signString;
- }
- /**
- * 使用 RSA 私钥 + SHA512 签名数组
- *
- * @param array $data 要签名的数组
- * @param string $privateKey 私钥内容(PEM格式)
- * @return string Base64 编码签名字符串
- */
- function handleSign(array $data, string $privateKey): string
- {
- $signString = $this->handleSignData($data);
- $pkey = openssl_pkey_get_private($privateKey);
- if (!$pkey) {
- throw new Exception('无效的 RSA 私钥');
- }
- $signature = '';
- $success = openssl_sign($signString, $signature, $pkey, OPENSSL_ALGO_SHA512);
- openssl_free_key($pkey);
- if (!$success) {
- throw new Exception('签名失败');
- }
- // 6. 返回 Base64 编码后的签名
- return base64_encode($signature);
- }
- /**
- * 签名效验
- *
- * @param array $data
- * @param string $publicKey
- * @param string $signstr
- *
- * @return string
- */
- function handleSignVerify(array $data, string $publicKey, string $signstr): string
- {
- $signString = $this->handleSignData($data);
- $public_key_res = openssl_get_publickey($publicKey);
- $res = openssl_verify($signString, base64_decode($signstr), $public_key_res, OPENSSL_ALGO_SHA512);
- if($res == 1){
- return true;
- }
- return false;
- }
- }
|