iceyan22 2021-02-15 17:49 采纳率: 100%
浏览 986
已采纳

STEAM 如何实现内购? PHP C#都行。

求steam实现内购的全部代码,或者测试案例。自己研究了半天ISteamMicroTxn 接口,结果每次都报错:Access is denied. Retrying will not help. Please verify your <pre>key=</pre> parameter.。求大佬指点迷津。w(゚Д゚)w

  • 写回答

7条回答 默认 最新

  • 歇歇 2021-02-15 20:55
    关注

    文档地址:https://partner.steamgames.com/doc/features/microtransactions/implementation

    1.服务器需要订单信息:
    ①用户信息

     

    'steamid' => '',
    'language' => '客户端游戏语言代码 – ISO 639-1 语言代码,客户端游戏正在使用的语言',
    'currency' => 'SO 4217 货币代码,对客户端扣款所使用的币种'
    

    ②订单信息

     

    'itemcount' => '购买总数(int)',
    'orderid' => '由您为此次购买指定的唯一的 64 位数字。 此数字也是此次交易的关键, 在 Steam 系统中引用该交易时使用(int)',
    'itemid[0]' => '商品id(int)',
    'qty[0]' =>'商品数量(int)',
    'amount[0]' => '商品总价值(单位:分)(int)',
    'description[0]' => '商品描述',
    

    ③游戏信息

     

    'key' => '网页 API 密钥',
    'appid' => '您的 Steam 游戏的唯一标识符'
    

    注意事项:
    currency字段由服务器获取,orderid由服务器生成外,其他信息均由游戏服务器提供。
    language虽由客户端提供,但客户端接口返回的language并不是iso 639-1标准的,转换如下:(键为客户端使用语言,值为web服务器使用语言)

     

    private function languages($language)
        {
            $languages = [
                'arabic' => 'ar',
                'bulgarian' => 'bg',
                'schinese' => 'zh-CN',
                'tchinese' => 'zh-TW',
                'czech' => 'cs',
                'danish' => 'da',
                'dutch' => 'nl',
                'english' => 'en',
                'finnish' => 'fi',
                'french' => 'fr',
                'german' => 'de',
                'greek' => 'el',
                'hungarian' => 'hu',
                'italian' => 'it',
                'japanese' => 'ja',
                'koreana' => 'ko',
                'norwegian' => 'no',
                'polish' => 'pl',
                'portuguese' => 'pt',
                'brazilian' => 'pt-BR',
                'romanian' => 'ro',
                'russian' => 'ru',
                'spanish' => 'es',
                'swedish' => 'sv',
                'thai' => 'th',
                'turkish' => 'tr',
                'ukrainian' => 'uk',
            ];
    
            return $languages[$language];
        }
    
    1.  

     

    正式地址:
    $baseUri = 'https://partner.steam-api.com/ISteamMicroTxn/';
    测试地址:
    $basrUriSandBox = 'https://partner.steam-api.com/ISteamMicroTxnSandbox/';
    

    curl https

     

    function curl_get_https($url){
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);  // 从证书中检查SSL加密算法是否存在
        $tmpInfo = curl_exec($curl);     //返回api的json对象
        //关闭URL请求
        curl_close($curl);
        return $tmpInfo;    //返回json对象
    }
    
    function curl_post_https($url,$data){ // 模拟提交数据函数
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $tmpInfo = curl_exec($curl); // 执行操作
        if (curl_errno($curl)) {
            echo 'Errno'.curl_error($curl);//捕抓异常
        }
        curl_close($curl); // 关闭CURL会话
        return $tmpInfo; // 返回数据,json格式
    }
    

    ①获取用户currency: https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#GetUserInfo

     

    private function getSteamUserInfo($steamId)
        {
            //GET https://partner.steam-api.com/ISteamMicroTxn/GetUserInfo/v2/
            $steamInfoUrl = $this->baseUri . 'GetUserInfo/v2/?key=%s&steamid=%s';
            $url = sprintf($steamInfoUrl, $this->apiKey, $steamId);
    
            $response = curl_post_https($url);
            $json = json_decode($response, true);
    
            if ($json['response']['result'] == 'Failure') {
                \Log::info('steam_user_info', $json);
                throw new \Exception('Steam Response Error');
            }
    
            return $json['response']['params'];
        }
    

    ②向steam发起购买: https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#InitTxn

     

    public function initOrder(Request $request)
        {
            $attributes = $request->only([
                'steamid', 'appid', 'language', 'itemid'
            ]);
           
            $userInfo = $this->getSteamUserInfo($attributes['steamid']);
            $attributes['currency'] = $userInfo['currency'];
            
             //生成唯一订单号
            $order = SteamOrders::query()->orderByDesc('created_at')->first(['orderid']);
            $attributes['orderid'] = $order ? $order->orderid + 1 : 10000000;
    
            $goods = $this->goods($attributes['itemid']);
             //订单信息
            $data = [
                'key' => $this->apiKey,
                'steamid' => $attributes['steamid'],
                'appid' => $attributes['appid'],
                'language' => $this->languages($attributes['language']),
                'itemcount' => 1,
                'orderid' => (int)$attributes['orderid'],
                'currency' => $attributes['currency'],
                'itemid[0]' => $goods['itemid'],
                'qty[0]' => 1,//(int)$attributes['qty'],
                'amount[0]' => $goods['amount'],
                'description[0]' => $goods['description'],
            ];
    
            //POST https://partner.steam-api.com/ISteamMicroTxn/InitTxn/v3/
            $initTxnUrl = $this->baseUri . 'InitTxn/v3/';
            $response = $this->curlPostHttps($initTxnUrl, $data);       
            $result = json_decode($response, true);
            $result = $result['response'];
    
            if ($result['result'] == 'Failure') {
                \Log::info('steam_init_order', $result);
    
                return ['code' => 500, 'message' => 'Steam Response Error'];
            }
    
            $attributes['amount'] = $goods['amount'];
            $attributes['description'] = $goods['description'];
            SteamOrders::create($attributes);
    
            return [
                'code' => 0,
                'data' => [
                    'orderid' => $attributes['orderid'],
                    'appid' => $attributes['appid']
                ]
            ];
        }
    

    ③完成订单:https://partner.steamgames.com/doc/webapi/ISteamMicroTxn#FinalizeTxn

     

    public function finishOrder(Request $request)
        {
            $userId = '';
    
            $attributes = $request->only(['appid', 'orderid']);
            $attributes['key'] = $this->apiKey;
    
            //POST https://partner.steam-api.com/ISteamMicroTxn/FinalizeTxn/v2/
            $finishTxnUrl = $this->baseUri . 'FinalizeTxn/v2/';
            //$response = $this->client->post($initTxnUrl, ['form_params' => $attributes, 'verify' => false]);
            $response = $this->curlPostHttps($finishTxnUrl, $attributes);
            $result = json_decode($response, true);
            $result = $result['response'];
    
            if ($result['result'] == 'Failure') {
                \Log::info('steam_finish_order', $result);
    
                return ['code' => 500, 'message' => 'Steam Response Error'];
            }
    
            $order = SteamOrders::query()->where('orderid', $attributes['orderid'])->first();
            $itemId = $order->itemid;
    
            $result = $this->sendUserGoods($userId, $itemId);
            $status = 2;
            if ($result) {
                $status = 3;
            }
    
            $order->user_id = $userId;
            $order->transid = $result['params']['transid'];
            $order->pay_state = $status;
            $order->save();
    
            return ['code' => 0];
        }
    

    后记:数据库设计

     

    Schema::create('steam_orders', function (Blueprint $table) {
                $table->increments('id');
                $table->integer('user_id')->nullable();
                $table->integer('orderid');
                $table->integer('transid')->nullable()->comment('steam交易id');
                $table->integer('steamid');
                $table->string('currency')->comment('货币类型');
                $table->string('appid');
                $table->string('language');
                $table->string('itemid', 50)->comment('商品id');
                $table->tinyInteger('qty')->default(1)->comment('购买数量');
                $table->bigInteger('amount')->default(0)->comment('总价:分');
                $table->string('description', 255)->comment('商品描述');
                $table->tinyInteger('pay_state')->default(1)->comment('交易状态:1未支付,2支付完成,3已发货');
                $table->timestamps();
            });



    https://www.jianshu.com/p/09a2d0174a4d
     

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改