李帅

1.重构合成脚本。

1 +<?php
2 +
3 +namespace App\Console\Commands;
4 +
5 +use App\Payment\GooglePayment;
6 +use Illuminate\Console\Command;
7 +
8 +class DevGoogle extends Command
9 +{
10 + /**
11 + * The name and signature of the console command.
12 + *
13 + * @var string
14 + */
15 + protected $signature = 'dev:gp';
16 +
17 + /**
18 + * The console command description.
19 + *
20 + * @var string
21 + */
22 + protected $description = 'Command description';
23 +
24 + /**
25 + * Create a new command instance.
26 + *
27 + * @return void
28 + */
29 + public function __construct()
30 + {
31 + parent::__construct();
32 + }
33 +
34 + /**
35 + * Execute the console command.
36 + *
37 + * @return int
38 + */
39 + public function handle()
40 + {
41 + $gp = new GooglePayment();
42 +
43 +
44 + return 0;
45 + }
46 +}
...@@ -33,11 +33,24 @@ class PayController extends Controller ...@@ -33,11 +33,24 @@ class PayController extends Controller
33 * Store a newly created resource in storage. 33 * Store a newly created resource in storage.
34 * 34 *
35 * @param \Illuminate\Http\Request $request 35 * @param \Illuminate\Http\Request $request
36 - * @return \Illuminate\Http\Response 36 + * @param \App\Payment\PaymentFactory $factory
37 + * @return \Illuminate\Http\JsonResponse
37 */ 38 */
38 - public function store(Request $request) 39 + public function store(Request $request, PaymentFactory $factory)
39 { 40 {
40 // 回调 41 // 回调
42 + $order_sn = $request->post('order_sn');
43 + $pay_type = $request->post('pay_type');
44 + $token = $request->post('token');
45 +
46 +// $order = Order::query()->where('order_sn', $order_sn)->first();
47 +//
48 +// if ($order->status != Order::UNPAID) return Response::fail('订单错误!');
49 +
50 + $payment = $factory->init($pay_type)->notify($order_sn, $token);
51 +
52 + if ($payment) return Response::success(['order_sn' => $order_sn], '支付成功');
53 + else return Response::fail('订单错误!');
41 } 54 }
42 55
43 /** 56 /**
......
...@@ -22,11 +22,11 @@ class GooglePayment implements PaymentInterface ...@@ -22,11 +22,11 @@ class GooglePayment implements PaymentInterface
22 22
23 const IS_SANDBOX = true; 23 const IS_SANDBOX = true;
24 24
25 - 25 + public $client;
26 26
27 public function __construct() 27 public function __construct()
28 { 28 {
29 - 29 + $this->client = $this->getGoogleClient();
30 } 30 }
31 31
32 32
...@@ -35,4 +35,122 @@ class GooglePayment implements PaymentInterface ...@@ -35,4 +35,122 @@ class GooglePayment implements PaymentInterface
35 { 35 {
36 // 查询订单对应的产品id 36 // 查询订单对应的产品id
37 } 37 }
38 +
39 + private function getGoogleClient()
40 + {
41 + // load our config.json that contains our credentials for accessing google's api as a json string
42 + $configJson = public_path().'/client_secret_724392566830-jv6gqcb7vv8q9vavihhu5siccdit35op.apps.googleusercontent.com.json';
43 +
44 + // define an application name
45 + $applicationName = 'Parlando一言临境';
46 +
47 + // create the client
48 + $client = new \Google_Client();
49 + $client->setApplicationName($applicationName);
50 + $client->setAuthConfig($configJson);
51 + $client->setAccessType('offline'); // necessary for getting the refresh token
52 + $client->setApprovalPrompt ('force'); // necessary for getting the refresh token
53 + // scopes determine what google endpoints we can access. keep it simple for now.
54 + $client->setScopes(
55 + [
56 + \Google\Service\Oauth2::USERINFO_PROFILE,
57 + \Google\Service\Oauth2::USERINFO_EMAIL,
58 + \Google\Service\Oauth2::OPENID,
59 + \Google_Service_AndroidPublisher::ANDROIDPUBLISHER,
60 + \Google\Service\Drive::DRIVE_METADATA_READONLY // allows reading of google drive metadata
61 + ]
62 + );
63 + $client->setIncludeGrantedScopes(true);
64 +
65 + // google 服务端默认获得受权
66 + $client->useApplicationDefaultCredentials();
67 + // 设置 google client_email
68 + $client->setSubject("client_email");
69 +
70 + return $client;
71 + }
72 +
73 + public function notify($order_sn, $token)
74 + {
75 + $order = Order::query()->where('order_sn', $order_sn)->first();
76 +
77 + if ($order->status != Order::UNPAID) return false;
78 +
79 + $validator =new \Google_Service_AndroidPublisher($this->client);
80 +
81 + $packageName = 'pub.yiyan.parlando.Parlando';
82 + $productId = 'test.yiyan.vip.1.month';
83 +// $token = '客户端传过来的 支付凭证';
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 +
116 + if ($resp['consumptionState'] != 1) return false;
117 +
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 +
145 + $user->buy_number += 1;
146 + $user->buy_amount += $order->pay_amount;
147 + $user->last_buy_time = Carbon::now();
148 + $user->save();
149 +
150 + /** 修改订单状态*/
151 + $order->status = Order::DONE;
152 + $order->save();
153 +
154 + return true;
155 + }
38 } 156 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
8 "php": "^7.3|^8.0", 8 "php": "^7.3|^8.0",
9 "dcat/laravel-admin": "2.*", 9 "dcat/laravel-admin": "2.*",
10 "fruitcake/laravel-cors": "^2.0", 10 "fruitcake/laravel-cors": "^2.0",
11 + "google/apiclient": "^2.0",
11 "guzzlehttp/guzzle": "^7.0.1", 12 "guzzlehttp/guzzle": "^7.0.1",
12 "jiannei/laravel-enum": "^3.0", 13 "jiannei/laravel-enum": "^3.0",
13 "jiannei/laravel-response": "^4.0", 14 "jiannei/laravel-response": "^4.0",
......
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://www.yiyan.pub/auth/google/callback"],"javascript_origins":["https://www.yiyan.pub","http://www.yiyan.pub"]}}
...\ No newline at end of file ...\ No newline at end of file