李帅

1.打印谷歌订阅日志

...@@ -38,9 +38,9 @@ class DevGoogle extends Command ...@@ -38,9 +38,9 @@ class DevGoogle extends Command
38 */ 38 */
39 public function handle() 39 public function handle()
40 { 40 {
41 - dd(1); 41 +// dd(1);
42 $gp = new GooglePayment(); 42 $gp = new GooglePayment();
43 - 43 + dd($gp->client);
44 44
45 return 0; 45 return 0;
46 } 46 }
......
...@@ -106,12 +106,12 @@ class PayController extends Controller ...@@ -106,12 +106,12 @@ class PayController extends Controller
106 // 106 //
107 } 107 }
108 108
109 - public function iapCallback(Request $request,$service) 109 + public function iapCallback(Request $request, PaymentFactory $factory, $service)
110 { 110 {
111 $all = $request->all(); 111 $all = $request->all();
112 - Log::debug($all['message']['data']);
113 - Log::debug(base64_decode($all['message']['data']));
114 112
115 - return 'ok'; 113 + $factory->init($service)->notify($all['message']['data']);
114 +
115 + return Response::ok();
116 } 116 }
117 } 117 }
......
...@@ -13,6 +13,7 @@ use App\Models\Order; ...@@ -13,6 +13,7 @@ use App\Models\Order;
13 use App\Models\User; 13 use App\Models\User;
14 use App\Models\UserProfile; 14 use App\Models\UserProfile;
15 use Carbon\Carbon; 15 use Carbon\Carbon;
16 +use Google\Service\AndroidPublisher\SubscriptionPurchasesAcknowledgeRequest;
16 use GuzzleHttp\Client; 17 use GuzzleHttp\Client;
17 use Illuminate\Support\Facades\Log; 18 use Illuminate\Support\Facades\Log;
18 use Illuminate\Support\Facades\Redis; 19 use Illuminate\Support\Facades\Redis;
...@@ -47,7 +48,11 @@ class GooglePayment implements PaymentInterface ...@@ -47,7 +48,11 @@ class GooglePayment implements PaymentInterface
47 // create the client 48 // create the client
48 $client = new \Google_Client(); 49 $client = new \Google_Client();
49 $client->setApplicationName($applicationName); 50 $client->setApplicationName($applicationName);
51 + try{
50 $client->setAuthConfig($configJson); 52 $client->setAuthConfig($configJson);
53 + }catch (\Google\Exception $exception){
54 + Log::debug('用户授权出错了'.$exception->getMessage());
55 + }
51 $client->setAccessType('offline'); // necessary for getting the refresh token 56 $client->setAccessType('offline'); // necessary for getting the refresh token
52 $client->setApprovalPrompt ('force'); // necessary for getting the refresh token 57 $client->setApprovalPrompt ('force'); // necessary for getting the refresh token
53 // scopes determine what google endpoints we can access. keep it simple for now. 58 // scopes determine what google endpoints we can access. keep it simple for now.
...@@ -60,97 +65,160 @@ class GooglePayment implements PaymentInterface ...@@ -60,97 +65,160 @@ class GooglePayment implements PaymentInterface
60 \Google\Service\Drive::DRIVE_METADATA_READONLY // allows reading of google drive metadata 65 \Google\Service\Drive::DRIVE_METADATA_READONLY // allows reading of google drive metadata
61 ] 66 ]
62 ); 67 );
63 - $client->setIncludeGrantedScopes(true); 68 +// $client->setIncludeGrantedScopes(true);
64 69
65 // google 服务端默认获得受权 70 // google 服务端默认获得受权
66 - $client->useApplicationDefaultCredentials(); 71 +// $client->useApplicationDefaultCredentials();
67 // 设置 google client_email 72 // 设置 google client_email
68 - $client->setSubject("client_email"); 73 +// $client->setSubject("client_email");
69 74
70 return $client; 75 return $client;
71 } 76 }
72 77
73 - public function notify($order_sn, $token) 78 +// public function notify($order_sn, $token)
79 +// {
80 +// $order = Order::query()->where('order_sn', $order_sn)->first();
81 +//
82 +// if ($order->status != Order::UNPAID) return false;
83 +//
84 +// $validator =new \Google_Service_AndroidPublisher($this->client);
85 +//
86 +// $packageName = 'pub.yiyan.parlando.Parlando';
87 +// $productId = 'test.yiyan.vip.1.month';
88 +//// $token = '客户端传过来的 支付凭证';
89 +// $optps = array();
90 +// /**
91 +// * 成功会返回
92 +// * 返回字段解释 https://developers.google.com/android-publisher/api-ref/purchases/products
93 +// *
94 +// * 返回字段解释 中文翻译
95 +// * consumptionState int 消费类产品的消费状态 0有待消费1已消耗
96 +// * developerPayload string onyx系统生成的唯一ID
97 +// * kind sgring 购买的对象
98 +// * orderId sgring 客户支付订单ID(google play 订单ID)
99 +// * purchaseState int 订单的采购状态 0购买1取消
100 +// * purchaseTimeMillis int 时间戳
101 +// * purchaseType int 扩展字段 0 测试 1促销
102 +// * Array(
103 +// * [consumptionState] => 1
104 +// * [developerPayload] => 你的订单号
105 +// * [kind] => androidpublisher#productPurchase
106 +// * [orderId] => google play 订单号
107 +// * [purchaseState] => 0
108 +// * [purchaseTimeMillis] => 1542187625018
109 +// * [purchaseType] =>
110 +// * )
111 +// */
112 +// try {
113 +// $resp = $validator->purchases_products->get($packageName, $productId, $token, $optps);
114 +// // 对象转数组
115 +// $resp = get_object_vars($resp);
116 +// } catch (\Exception $e) {
117 +// Log::debug('got error = ' . $e->getMessage() . PHP_EOL);
118 +// throw new \Exception('got error = ' . $e->getMessage() . PHP_EOL);
119 +// }
120 +//
121 +// if ($resp['consumptionState'] != 1) return false;
122 +//
123 +// /** 修改订单状态*/
124 +// $order->pay_time = Carbon::now();
125 +// $order->status = Order::PAID;
126 +// $order->save();
127 +//
128 +// /** 给用户加会员*/
129 +// $goods = MembershipGood::query()->find($order->order_goods->goods_id);
130 +// if ($goods->limit_unit == '月') {
131 +// $days = intval($goods->limit_days) * 30;// 计算天数
132 +// } elseif ($goods->limit_unit == '年') {
133 +// $days = intval($goods->limit_days) * 365;// 计算天数
134 +// } else {
135 +// $days = intval($goods->limit_days) * 1;// 计算天数
136 +// }
137 +// $user = UserProfile::query()->find($order->user_id);
138 +// if ($user->is_vip == 0){
139 +// $user->is_vip = 1;
140 +// $user->create_vip_time = Carbon::now();
141 +// $user->expire_vip_time = Carbon::now()->addDays($days);
142 +// }else{
143 +// if (Carbon::now()->gte($user->expire_vip_time)){ // 已经过期了
144 +// $user->expire_vip_time = Carbon::now()->addDays($days);
145 +// }else{
146 +// $user->expire_vip_time = Carbon::parse($user->expire_vip_time)->addDays($days);
147 +// }
148 +// }
149 +//
150 +// $user->buy_number += 1;
151 +// $user->buy_amount += $order->pay_amount;
152 +// $user->last_buy_time = Carbon::now();
153 +// $user->save();
154 +//
155 +// /** 修改订单状态*/
156 +// $order->status = Order::DONE;
157 +// $order->save();
158 +//
159 +// return true;
160 +// }
161 +
162 + public function notify($string)
74 { 163 {
75 - $order = Order::query()->where('order_sn', $order_sn)->first(); 164 + //subscriptionNotification(订阅相关)、oneTimeProductNotification(一次性购买相关)testNotification(测试发布相关) 三个不会同时存在任意2个
165 + //subscriptionNotification说明
166 +
167 + //参数名 说明
168 + //version 此通知的版本。最初,此值为“1.0”。此版本与其他版本字段不同。
169 + //notificationType int 订阅的 notificationType 可以参考下面的表
170 + //purchaseToken 购买订阅时向用户设备提供的令牌
171 + //subscriptionId 所购买订阅的 ID(例如“monthly001”)
172 +
173 + //SUBSCRIPTION_RECOVERED - 从帐号保留状态恢复了订阅。
174 + //SUBSCRIPTION_RENEWED - 续订了处于活动状态的订阅。
175 + //SUBSCRIPTION_CANCELED - 自愿或非自愿地取消了订阅。如果是自愿取消,在用户取消时发送。
176 + //SUBSCRIPTION_PURCHASED - 购买了新的订阅。
177 + //SUBSCRIPTION_ON_HOLD - 订阅已进入帐号保留状态(如果已启用)。
178 + //SUBSCRIPTION_IN_GRACE_PERIOD - 订阅已进入宽限期(如果已启用)。
179 + //SUBSCRIPTION_RESTARTED - 用户已通过 Play > 帐号 > 订阅重新激活其订阅(需要选择使用订阅恢复功能)。
180 + //SUBSCRIPTION_PRICE_CHANGE_CONFIRMED - 用户已成功确认订阅价格变动。
181 + //SUBSCRIPTION_DEFERRED - 订阅的续订时间点已延期。
182 + //SUBSCRIPTION_PAUSED - 订阅已暂停。
183 + //SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED - 订阅暂停计划已更改。
184 + //SUBSCRIPTION_REVOKED - 用户在到期时间之前已撤消订阅。
185 + //SUBSCRIPTION_EXPIRED - 订阅已到期。
186 +
187 + $data = base64_decode($string);
188 +
189 + $packageName = $data['packageName'];
190 + if (isset($data['subscriptionNotification'])) {
191 + $subscriptionId = $data['subscriptionNotification']['subscriptionId'];
192 + $purchaseToken = $data['subscriptionNotification']['purchaseToken'];
193 +
194 +
195 + //1.3. 根据解密后的内容去google接口做查询校验并发货(关键参数expiryTimeMillis)
196 + //根据解密后的内容去google接口做校验
197 + //Google文档地址
198 + //请求域名(Get/form):
199 + //https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}
200 + $validator =new \Google_Service_AndroidPublisher($this->client);
201 + $resp = $validator->purchases_subscriptions->get($packageName, $subscriptionId, $purchaseToken);
76 202
77 - if ($order->status != Order::UNPAID) return false; 203 + Log::debug('新订阅人员:====================');
204 + Log::debug(var_export($resp,true));
205 + Log::debug("购买状态" . $resp->getAcknowledgementState()); //0。待确认 1. 已确认
78 206
79 - $validator =new \Google_Service_AndroidPublisher($this->client); 207 + //1.4. 消耗该笔订单
208 + //Google文档地址
209 + //请求域名(Post/form)
210 + //https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}:acknowledge
80 211
81 - $packageName = 'pub.yiyan.parlando.Parlando'; 212 + $acknowledge = new SubscriptionPurchasesAcknowledgeRequest();
82 - $productId = 'test.yiyan.vip.1.month'; 213 + $acknowledge->developerPayload = ''; // todo 可以将我们系统的订单号、用户支付金额等存入谷歌订单里
83 -// $token = '客户端传过来的 支付凭证'; 214 + $resp = $validator->purchases_subscriptions->acknowledge($packageName, $subscriptionId, $purchaseToken,$acknowledge);
84 - $optps = array();
85 - /**
86 - * 成功会返回
87 - * 返回字段解释 https://developers.google.com/android-publisher/api-ref/purchases/products
88 - *
89 - * 返回字段解释 中文翻译
90 - * consumptionState int 消费类产品的消费状态 0有待消费1已消耗
91 - * developerPayload string onyx系统生成的唯一ID
92 - * kind sgring 购买的对象
93 - * orderId sgring 客户支付订单ID(google play 订单ID)
94 - * purchaseState int 订单的采购状态 0购买1取消
95 - * purchaseTimeMillis int 时间戳
96 - * purchaseType int 扩展字段 0 测试 1促销
97 - * Array(
98 - * [consumptionState] => 1
99 - * [developerPayload] => 你的订单号
100 - * [kind] => androidpublisher#productPurchase
101 - * [orderId] => google play 订单号
102 - * [purchaseState] => 0
103 - * [purchaseTimeMillis] => 1542187625018
104 - * [purchaseType] =>
105 - * )
106 - */
107 - try {
108 - $resp = $validator->purchases_products->get($packageName, $productId, $token, $optps);
109 - // 对象转数组
110 - $resp = get_object_vars($resp);
111 - } catch (\Exception $e) {
112 - Log::debug('got error = ' . $e->getMessage() . PHP_EOL);
113 - throw new \Exception('got error = ' . $e->getMessage() . PHP_EOL);
114 - }
115 215
116 - if ($resp['consumptionState'] != 1) return false; 216 + Log::debug('消耗结果:====================');
117 - 217 + Log::debug(var_export($resp,true));
118 - /** 修改订单状态*/
119 - $order->pay_time = Carbon::now();
120 - $order->status = Order::PAID;
121 - $order->save();
122 -
123 - /** 给用户加会员*/
124 - $goods = MembershipGood::query()->find($order->order_goods->goods_id);
125 - if ($goods->limit_unit == '月') {
126 - $days = intval($goods->limit_days) * 30;// 计算天数
127 - } elseif ($goods->limit_unit == '年') {
128 - $days = intval($goods->limit_days) * 365;// 计算天数
129 - } else {
130 - $days = intval($goods->limit_days) * 1;// 计算天数
131 - }
132 - $user = UserProfile::query()->find($order->user_id);
133 - if ($user->is_vip == 0){
134 - $user->is_vip = 1;
135 - $user->create_vip_time = Carbon::now();
136 - $user->expire_vip_time = Carbon::now()->addDays($days);
137 - }else{
138 - if (Carbon::now()->gte($user->expire_vip_time)){ // 已经过期了
139 - $user->expire_vip_time = Carbon::now()->addDays($days);
140 - }else{
141 - $user->expire_vip_time = Carbon::parse($user->expire_vip_time)->addDays($days);
142 - }
143 - }
144 218
145 - $user->buy_number += 1; 219 + // todo 发货
146 - $user->buy_amount += $order->pay_amount;
147 - $user->last_buy_time = Carbon::now();
148 - $user->save();
149 220
150 - /** 修改订单状态*/ 221 + }
151 - $order->status = Order::DONE;
152 - $order->save();
153 222
154 - return true;
155 } 223 }
156 } 224 }
...\ No newline at end of file ...\ No newline at end of file
......
1 -{"web":{"client_id":"724392566830-jv6gqcb7vv8q9vavihhu5siccdit35op.apps.googleusercontent.com","project_id":"pc-api-7482901338487549764-603","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"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","redirect_uris":["https://api.yiyan.pub/auth/google/callback","http://api.parlando.ink/auth/google/callback","https://www.yiyan.pub/auth/google/callback"],"javascript_origins":["https://www.yiyan.pub","http://www.yiyan.pub","http://api.parlando.ink","https://api.parlando.ink"]}}
...\ No newline at end of file ...\ No newline at end of file
1 +{"web":{"client_id":"724392566830-jv6gqcb7vv8q9vavihhu5siccdit35op.apps.googleusercontent.com","project_id":"pc-api-7482901338487549764-603","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","redirect_uris":["https://api.parlando.ink/auth/google/callback"],"javascript_origins":["https://www.yiyan.pub","https://api.parlando.ink"]}}
...\ No newline at end of file ...\ No newline at end of file
......
1 +{
2 + "type": "service_account",
3 + "project_id": "pc-api-7482901338487549764-603",
4 + "private_key_id": "566eccf76b913f7999fe0f2b433c6970ebf15eb8",
5 + "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCd4Ujb46oBo1A3\nxqC0+tYJB5exDYLXmL0NVYdYYh14MYcqWigYt4NZjlyWvWHktLEBKMXddEiHCmv/\nCQzl/LBz8ONhhBaSXBxCJvmZUcuq5C1ciCQ353rohBbT4BCcDo3NphkBs/DDzgIh\nuljBS7XVoRoyv2+yrWqaricyCNqUccvDaFk3R9AZDTIYkeD4qE2reTE5Z05LOMKv\nxaUeSFZoeXb6WWQklU5TxYVFgaFg1iANyKBBVCWEylK7w9PaZTyFZnxsONTDyVxn\nm5//VfZxYg07cNO8/xLSUj3NBT22E5lEyjRgMBVX4DFvxpZrOlTVY1XO7cND5+yD\noLvDcobjAgMBAAECggEAJzHcsqpMdGek7JPlJcj4BfnakNv31apXlM3c8fY5trMl\nCUCkn64/b6ZGGi4d9XdeUhlbNeU+dDgEI6aNizM2YzI0YOs351HyugGPCZ8i3uQS\n1tv9kdtnyf2w5RzFQtjiH2HS53dSmGm2YcUvb51qIQUDygF4q3Ud+BSwKl3EVgGe\nB7VtoXKYkdLDNytsWm8ifzuc6PViY2VFOA7t9qyH9ytE5klvn9GjJzht6Cm32iYO\ntjikU7SeNZJNm0a6wcI00HzMPSLk5jN+p1mOvV37dyQpPwizHR790RYkoy15GicP\nE1j1j5bQc06emXcUFOWYnXtc7J/ECzFIgbs4K/i6QQKBgQDcE8eDZLrgxSOuscu1\n3UyYsCCM6L3BCFnLIbRjvNd1yA4w8Gq3RJ6pINEAvXgayj2517X10QwF0V+AU8UB\nuEHrc/2PtpRozSxKd/CCMT2Y9qr+4yfh9cDTQbBXXzO24uzB5+c4Zo9LR4FzVgKh\nFr8lnXdUD+qWUYXF0f6DzJrfkwKBgQC3poLC5VV8fa6WSK4B+quHcMFWO0pON3P+\njTckyBW7t+Ad5DIdW01LqAa4ciQFuZcYcnDH41lOpkliIbA+CGGVsN6DQhIHDn4H\nOTVDhZRO7ErcEfPhq0P+C50fBVb7bFcQWMOAQxIbwWXLCHZtCc93S//beucYQbIe\nVrFTQrMtcQKBgHo8njdzznyj4uLYLC6yYSX5xcqeRy8dZUp3SQuQyxfHa2JxVsS+\nX2XPLWc81aYDqO89SfrkBsqAdYwAe08uOab+wNp+7cWcGDqwjayyjuUUNPvnzbIq\n3tQ4CyssXLv7JMe69+mSxYppiBQ4tLMmwDqzUKEnSgP9+dBbiANKtMbzAoGAHZBK\ngIFWj6HT1xGAIYVu03DNTspgndLDc3jcJamoBf4FsAoqHxuxh7pWyp5lOh60OhVC\nHot0tvqB2bA+pN3Ih8ZfK5YZPNWSaCtHbcU1KLdVHbQuJGfjnCPWeUXsyLCaG2GO\npzkk0x8A+fw0xDzODxBG8dgJF5iLyeJ+zT5xhaECgYEAlGXBbqd8hmwYQscTMLjq\nLGzjid9WeFRiV8xCUKFF+ToTBga7j899uRQdWDTpQRc+QSs3nspPJ9Splvbxk9Xz\n5qiIiX3qBFxyCNEH8c9EwQtLfwDkD2qFD68/5cFTyG61uYmKNNtjIa7p4gXF56E7\nLo1vnD2GtG62LkJfzJnCsaE=\n-----END PRIVATE KEY-----\n",
6 + "client_email": "google-pay-for-parlando@pc-api-7482901338487549764-603.iam.gserviceaccount.com",
7 + "client_id": "115677870448624637412",
8 + "auth_uri": "https://accounts.google.com/o/oauth2/auth",
9 + "token_uri": "https://oauth2.googleapis.com/token",
10 + "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11 + "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/google-pay-for-parlando%40pc-api-7482901338487549764-603.iam.gserviceaccount.com"
12 +}