Android Google购买PHP服务器端验证(订阅购买和一次性购买)
一、订阅购买验证
android端采用google service account进行校验
1、打开https://cloud.google.com/console创建一个project;
2、打开project->APIs & auth->Credentials点击CREATE NEW CLIENT ID创建一个SERVICE ACCOUNT;
3、打开project->APIs & auth->APIs Google Play Android Developer API状态打开;
4、打开https://play.google.com/apps/publish/添加SERVICE ACCOUNT的查询权限;
5、打开Settings->User account & rights->Invite new user submit 添加刚才创建的SERVICE ACCOUNT;
6、然后勾选 查看财务报表 选项,增加查看订单的权限;
以上设定好后才能有权限验证课金信息,同一个google play账号下只需设定一次。
7、借助三方库
svn checkout http://google-api-php-client.googlecode.com/svn/trunk/ google-api-php-client-read-only
或者 https://github.com/zhoutingze/adtuu.git
require_once 'service/Google_Model.php';
require_once 'service/Google_Service.php';
require_once 'service/Google_ServiceResource.php';
require_once 'auth/Google_AssertionCredentials.php';
require_once 'auth/Google_Signer.php';
require_once 'auth/Google_P12Signer.php';
require_once 'service/Google_BatchRequest.php';
require_once 'external/URITemplateParser.php';
require_once 'auth/Google_Auth.php';
require_once 'cache/Google_Cache.php';
require_once 'io/Google_IO.php';
require_once('service/Google_MediaFileUpload.php'); $client_id = '175160586549-4vlcm5piovihb4jt3sd35cqi4tfxxxxx.apps.googleusercontent.com';
$account_name = '175160586549-4vlcm5piovihb4jt3sd35cqi4txxxxx@developer.gserviceaccount.com';
$key_file_name = 'MaTuRi-2b0228176bc8.p12'; $receipt = '{"orderId":"12999763169054705758.1343513511797676","packageName":"jp.maturi.android.hsb","productId":"m_member_highspeedboyz_2.99","purchaseTime":1410833767578,"purchaseState":0,"developerPayload":"CAQEAhaYH9MrPxYOPrLJAyFCdpYC76V6MPgu0v9","purchaseToken":"hnmmfkliefklbeeenooidabh.AO-J1OwRIVqhDtAElccXHbeEARLgpdaDgGFRfixj97lQyb-mOhnZydhgohqhnPgd0k8BD0InF7weqGcKhRWF6cfGEAQDxEZGv_JiDk3bCIS1hDOMUf8hCHQOOwowEYOBm6BmERQKazeV3xUNWU-cnVk0CZAdvtTlYA"}';
$receipt = json_decode($receipt, true); try {
$client = new Google_Client();
$client->setApplicationName($receipt['packageName']);
$client->setClientId($client_id); $key_file = APPPATH . 'config/' . ENVIRONMENT . '/android_purchase_file/' . $key_file_name;
$key = file_get_contents($key_file); $auth = new Google_AssertionCredentials(
$account_name,
array('https://www.googleapis.com/auth/androidpublisher'),
$key
); $client->setAssertionCredentials($auth);
$AndroidPublisherService = new Google_AndroidPublisherService($client);
$res = $AndroidPublisherService->purchases->get(
$receipt['packageName'],
$receipt['productId'],
$receipt['purchaseToken']
); $status = 0;
if (isset($res['validUntilTimestampMsec'])) {
$current_time = time();
$valid_time = $res['validUntilTimestampMsec'] / 1000;
if ($current_time < $valid_time) {
$status = 1;
}
} else {
throw new Exception('Invalid response data');
} // 其他操作 当然这里还需要验证包名是否一致
} catch (Exception $e) {
// 异常
}
二、一次性永久购买(比如金币购买)
// rsa_key这个是google购买中配置的
$rsa_key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmqt0a6kpHbqAdBJWLnxtBesukwJQ2SP/20XXIMqKYdBay3llLxZyGanzyrnq8+90DMAT40JJJq7pDNZd3vtJU/eRZBN4vUA4VscoF5GrX/7gQ3ThxPvypTkzxmcrCKPv/SWRoXhpA1Vjh+U7VSL6LJYqOhR6IT5UrcgWkgdf6EOvJ4KGDC1M5nVqFFhz6/lXc+uASC9pVxh6V+8Eh4ZvqDkWyBKybsbUKTOgDViMJWXujygRu3iTTJcRT2rzTrWXj8hHWkZpoU1hPg64M1QK1PSeGU7+lKgCvkHcO0ZO+VqrZ+ZUnBiVghcHz/QnxeSFLsX0mOHWDAsNNtFVDRkFjwIDAQAB';
// signature 和 signed_data是购买后google返回的,好像在测试环境中取不到其中的某一个值,android包要打阿尔法版本才有
$receipt = '{"signature":"ZkF1AAbUon1HI0K54dLlRYd7c+j1cKkaWiYuJzGyAZtYIbZgrgTJXb\/Xu0XgwrS0SN4sFuvmseYy4gBXM+Iljs6JySLblQSAqIqZFhhWutmAyO13c17ZJautGgePmti9o9+qxa92X1Pt4BKuV\/zDPTbgBHaVgCE1T1sKaHhOdvppZgYxFN1HSqe3E4c57A4duLK0f7prdmA\/k0pqZe9Pjv3I5Lf9HhS6QHFPL3vhaN8LMHUbHp\/02UFXDrIgJGK6V3JFSTnYrHsnWKMs8Z6qzAFiEELvvdHoHOG42e1J7dZhnUlzhmheTbtePkwUlRRzq0lU7WP6foyc5uVBLT01vQ==","signed_data":"{\"orderId\":\"12999763169054705758.1378495280758690\",\"packageName\":\"jp.maturi.android.xxxx\",\"productId\":\"inapppurchase_xxxx_4.99\",\"purchaseTime\":1418299229881,\"purchaseState\":0,\"developerPayload\":\"PraisePurchase_CAQEAhaYH9MrPxYOPrLJAyFCdpYC76V6MPgu0v9\",\"purchaseToken\":\"odepcbhgckffgokgcdcfaiei.AO-J1Oz8Ex89Uw_urARZhhyP04vPI18xYd_0Gs1YY6PF9EIkgRk3wPGFba6oOER-Yel-M7A7fcBc-LR3ZQdLTYFcyKy5TQHWUyagyMWXjh2gf7SIEiv02JzGQbSUkOXlr5KYc9vc4KSZmAkjqyeCuu2DBLxAwN6rb8DcK-Y_VCyGioGkricYgmE\"}"}';
$receipt = json_decode($receipt, true);
$signed_data = $receipt->signed_data;
$signature = $receipt->signature;
_openssl_verify($signed_data, $signature, $rsa_key); /**
* google play in-app-billing verification
* 「購入情報」を$signed_data
* 「暗号化された署名」を$signatureとします。
* 「公開鍵」を使用するために用意するものは、PEM形式の証明書です。
* まずDeveloper Console上で取得したDER(Distinguished Encoding Rules)形式を、
* PEM(Privacy Enhanced Mail)形式に変換したものを用います。
* PEMはBase64エンコードされたデータを含み、
* ヘッダーとフッターを付加したフォーマットですので、
* ヘッダーとフッターの間にBase64エンコードされた文字列が入っていればOKです。
* ヘッダーとフッターは次のものを利用します。
*/
private function _openssl_verify($signed_data, $signature, $rsa_key)
{
// RSA(PEM形式)公開鍵の生成
$cert = "-----BEGIN PUBLIC KEY-----" . PHP_EOL .
chunk_split($rsa_key, 64, PHP_EOL) .
"-----END PUBLIC KEY-----"; // openssl_get_publickey()はopenssl_pkey_get_public()のエイリアス
$pubkey = openssl_get_publickey($cert);
if (false === $pubkey) {
exit('error');
} // 署名をBase64デコードする(バイナリになる)
$signature = base64_decode($signature); // openssl_verify()のデフォルトアルゴリズムはSHA1なので、
// OPENSSL_ALGO_SHA1は渡さなくてもよい
$result = openssl_verify($signed_data, $signature, $pubkey, OPENSSL_ALGO_SHA1); // キーをメモリから解放
openssl_free_key($pubkey); var_dump($result); return $result;
}
Android Google购买PHP服务器端验证(订阅购买和一次性购买)的更多相关文章
- IOS苹果购买PHP服务器端验证(订阅购买和一次性购买通用)
// 正式环境验证地址 $ios_verify_url = 'https://buy.itunes.apple.com/verifyReceipt'; // 测试环境验证地址 $ios_sandbox ...
- SDK接入(2)之Android Google Play内支付(in-app Billing)接入
SDK接入(2)之Android Google Play内支付(in-app Billing)接入 继上篇SDK接入(1)之Android Facebook SDK接入整理完Facebook接入流程之 ...
- Android Google AdMob 广告接入示例
Android Google AdMob 广告接入示例 [TOC] 首先请大家放心,虽然 Google搜索等服务被qiang了,但是 广告服务国内还是可以用的,真是普天同庆啊~~~噗! 其实这篇文章也 ...
- android loginDemo +WebService用户登录验证
android loginDemo +WebService用户登录验证 本文是基于android4.0下的loginActivity Demo和android下的Webservice实现的.l ...
- (6)Xamarin.android google map v2
原文 Xamarin.android google map v2 Google Map v1已经在2013年的3月开始停止支持了,目前若要在你的Android手机上使用到Google Map,就必须要 ...
- Android Google Map v2具体解释:开发环境配置
Android Google Map v2具体解释:开发环境配置 --转载请注明出处:coder-pig 说在前面: 说到地 ...
- Google Authenticator(谷歌身份验证器)C#版
摘要:Google Authenticator(谷歌身份验证器),是谷歌公司推出的一款动态令牌工具,解决账户使用时遭到的一些不安全的操作进行的"二次验证",认证器基于RFC文档中的 ...
- Google authenticator 谷歌身份验证,实现动态口令
Google authenticator 谷歌身份验证,实现动态口令 google authenticator php 服务端 使用PHP类 require_once '../PHPGangsta/G ...
- FineUI(开源版)v6.0中FState服务器端验证的实现原理
前言 1. FineUI(开源版)是完整开源,最早发起于 2008-04,下载全部源代码:http://fineui.codeplex.com/ 2. 你可以通过捐赠作者来支持FineUI(开源版)的 ...
随机推荐
- 关于struts2的modelDriven
今天做毕业设计,前台往后台赋值,习惯性的用了modelDriven.但是刚写完就奇怪它的机理是怎样的,它怎么知道我前台传的参是哪个Model的属性(之前用servlet都是手动),于是手贱的ctrl点 ...
- C#中ROUND函数的问题 解决
ROUND()是C#中math的一个成员函数.System.Math.Round(),这个函数有四种用法,最长用的是对小数点位数的舍入.但这和现实生活中的“四舍五入”有一定区别,也有别JAVA中Mat ...
- 每天一个Linux命令(2):cd
转自:http://www.cnblogs.com/peida/archive/2012/10/24/2736501.html Linux cd命令可以说是Linux中最基本的命令语句,其他的命令语句 ...
- Eclipse+Axis使用WSDL文件生成Web Service服务端/客户端
JDK版本:1.5.0_22 Eclipse版本:Helios Service Release 2(3.6.2) WSDL文件的创建过程见http://blog.csdn.net/a19881029/ ...
- HTML5 indexedDB数据库的入门学习(一)
笔者早些时间看过web sql database,但是不再维护和支持,所以最近初步学习了一下indexedDB数据库,首先indexedDB(简称IDB)和web sql database有很大的差别 ...
- poj 2723 2-SAT问题
思路:二分枚举能开的门的数量,将每次枚举转换成2-SAT问题.这里存在的矛盾是假设有门上a,b两个锁,a锁对应于1号钥匙,而一号钥匙的配对是2号钥匙,b锁对应于3号钥匙,3号的配对是4号钥匙.那么2号 ...
- 本机连接虚拟机Oracle时报错的解决办法
虚拟机安装了Oracle服务器(桌面类)和客户端,里面使用plsql连接自己没有问题. 在本机连接虚拟机没有成功.虚拟机的地址是192.168.126.132,已经确认本机能ping通虚拟机. 先是报 ...
- [转]Ubuntu中无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
sudo apt-get install git E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用) E: 无法锁定管理目录(/var/lib/dpkg/ ...
- jquery jsonp实现跨域
html代码: $("#testJsonp").click(function(){ $.ajax({ url: "http://www.test.cc/1.php&quo ...
- Slickflow.NET 开源工作流引擎基础介绍(六)--模块化架构设计和实践
前言:在集成Slickflow.NET 引擎组件过程中,引擎组件需要将用户,角色等资源数据读取进来,供引擎内部调用:而企业客户都是有自己的组织架构模型,在引入模块化架构设计后,引擎组件的集成性更加友好 ...