Showing
5 changed files
with
183 additions
and
4 deletions
app/Console/Commands/DevGoogle.php
0 → 100644
| 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", | ... | ... |
public/client_secret_724392566830-jv6gqcb7vv8q9vavihhu5siccdit35op.apps.googleusercontent.com.json
0 → 100644
| 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 |
-
Please register or login to post a comment