GooglePayment.php 9.78 KB
<?php
/**
 * Created by PhpStorm.
 * User: lishuai
 * Date: 2022/2/15
 * Time: 4:23 PM
 */

namespace App\Payment;

use App\Models\MembershipGood;
use App\Models\Order;
use App\Models\User;
use App\Models\UserProfile;
use Carbon\Carbon;
use Google\Service\AndroidPublisher\SubscriptionPurchasesAcknowledgeRequest;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class GooglePayment implements PaymentInterface
{

    const IS_SANDBOX = true;

    public $client;

    public function __construct()
    {
        $this->client = $this->getGoogleClient();
    }



    public function prepare(Order $order)
    {
        // 查询订单对应的产品id
    }

    private function getGoogleClient()
    {
//        // load our config.json that contains our credentials for accessing google's api as a json string
//        $configJson = public_path().'/client_secret_724392566830-jv6gqcb7vv8q9vavihhu5siccdit35op.apps.googleusercontent.com.json';
//
//        // define an application name
//        $applicationName = 'Parlando一言临境';
//
//        // create the client
//        $client = new \Google_Client();
//        $client->setApplicationName($applicationName);
//        try{
//            $client->setAuthConfig($configJson);
//        }catch (\Google\Exception $exception){
//            Log::debug('用户授权出错了'.$exception->getMessage());
//        }
//        $client->setAccessType('offline'); // necessary for getting the refresh token
//        $client->setApprovalPrompt ('force'); // necessary for getting the refresh token
//        // scopes determine what google endpoints we can access. keep it simple for now.
//        $client->setScopes(
//            [
//                \Google\Service\Oauth2::USERINFO_PROFILE,
//                \Google\Service\Oauth2::USERINFO_EMAIL,
//                \Google\Service\Oauth2::OPENID,
//                \Google_Service_AndroidPublisher::ANDROIDPUBLISHER,
//                \Google\Service\Drive::DRIVE_METADATA_READONLY // allows reading of google drive metadata
//            ]
//        );
//        $client->setIncludeGrantedScopes(true);
//
//        // google 服务端默认获得受权
//        $client->useApplicationDefaultCredentials();
//        // 设置 google  client_email
//        $client->setSubject("client_email");


        $credentials_file = public_path().'/pc-api-7482901338487549764-603-566eccf76b91.json';
        $client = new \Google_Client();
        try{
            $client->setAuthConfig($credentials_file);
        }catch (\Google\Exception $exception){
            Log::debug('用户授权出错了'.$exception->getMessage());
        }
        $applicationName = 'Parlando一言临境';
        $client->setApplicationName($applicationName);
        $client->setScopes(
            [
                \Google_Service_AndroidPublisher::ANDROIDPUBLISHER,
            ]
        );

        return $client;
    }

//    public function notify($order_sn, $token)
//    {
//        $order = Order::query()->where('order_sn', $order_sn)->first();
//
//        if ($order->status != Order::UNPAID) return false;
//
//        $validator =new \Google_Service_AndroidPublisher($this->client);
//
//        $packageName = 'pub.yiyan.parlando.Parlando';
//        $productId = 'test.yiyan.vip.1.month';
////        $token = '客户端传过来的 支付凭证';
//        $optps = array();
//        /**
//         * 成功会返回
//         * 返回字段解释   https://developers.google.com/android-publisher/api-ref/purchases/products
//         *
//         * 返回字段解释 中文翻译
//         * consumptionState  int  消费类产品的消费状态  0有待消费1已消耗
//         * developerPayload  string onyx系统生成的唯一ID
//         * kind sgring 购买的对象
//         * orderId sgring 客户支付订单ID(google play 订单ID)
//         * purchaseState  int  订单的采购状态 0购买1取消
//         * purchaseTimeMillis int 时间戳
//         * purchaseType int 扩展字段 0 测试 1促销
//         * Array(
//         * [consumptionState] => 1
//         * [developerPayload] => 你的订单号
//         * [kind] => androidpublisher#productPurchase
//         * [orderId] => google play 订单号
//         * [purchaseState] => 0
//         * [purchaseTimeMillis] => 1542187625018
//         * [purchaseType] =>
//         * )
//         */
//        try {
//            $resp = $validator->purchases_products->get($packageName, $productId, $token, $optps);
//            // 对象转数组
//            $resp = get_object_vars($resp);
//        } catch (\Exception $e) {
//            Log::debug('got error = ' . $e->getMessage() . PHP_EOL);
//            throw new \Exception('got error = ' . $e->getMessage() . PHP_EOL);
//        }
//
//        if ($resp['consumptionState'] != 1) return false;
//
//        /** 修改订单状态*/
//        $order->pay_time = Carbon::now();
//        $order->status = Order::PAID;
//        $order->save();
//
//        /** 给用户加会员*/
//        $goods = MembershipGood::query()->find($order->order_goods->goods_id);
//        if ($goods->limit_unit == '月') {
//            $days = intval($goods->limit_days) * 30;// 计算天数
//        } elseif ($goods->limit_unit == '年') {
//            $days = intval($goods->limit_days) * 365;// 计算天数
//        } else {
//            $days = intval($goods->limit_days) * 1;// 计算天数
//        }
//        $user = UserProfile::query()->find($order->user_id);
//        if ($user->is_vip == 0){
//            $user->is_vip = 1;
//            $user->create_vip_time = Carbon::now();
//            $user->expire_vip_time = Carbon::now()->addDays($days);
//        }else{
//            if (Carbon::now()->gte($user->expire_vip_time)){    // 已经过期了
//                $user->expire_vip_time = Carbon::now()->addDays($days);
//            }else{
//                $user->expire_vip_time = Carbon::parse($user->expire_vip_time)->addDays($days);
//            }
//        }
//
//        $user->buy_number += 1;
//        $user->buy_amount += $order->pay_amount;
//        $user->last_buy_time = Carbon::now();
//        $user->save();
//
//        /** 修改订单状态*/
//        $order->status = Order::DONE;
//        $order->save();
//
//        return true;
//    }

    public function notify($string)
    {
        //subscriptionNotification(订阅相关)、oneTimeProductNotification(一次性购买相关)testNotification(测试发布相关) 三个不会同时存在任意2个
        //subscriptionNotification说明

        //参数名 说明
        //version 此通知的版本。最初,此值为“1.0”。此版本与其他版本字段不同。
        //notificationType int 订阅的 notificationType 可以参考下面的表
        //purchaseToken 购买订阅时向用户设备提供的令牌
        //subscriptionId 所购买订阅的 ID(例如“monthly001”)

        //SUBSCRIPTION_RECOVERED - 从帐号保留状态恢复了订阅。
        //SUBSCRIPTION_RENEWED - 续订了处于活动状态的订阅。
        //SUBSCRIPTION_CANCELED - 自愿或非自愿地取消了订阅。如果是自愿取消,在用户取消时发送。
        //SUBSCRIPTION_PURCHASED - 购买了新的订阅。
        //SUBSCRIPTION_ON_HOLD - 订阅已进入帐号保留状态(如果已启用)。
        //SUBSCRIPTION_IN_GRACE_PERIOD - 订阅已进入宽限期(如果已启用)。
        //SUBSCRIPTION_RESTARTED - 用户已通过 Play > 帐号 > 订阅重新激活其订阅(需要选择使用订阅恢复功能)。
        //SUBSCRIPTION_PRICE_CHANGE_CONFIRMED - 用户已成功确认订阅价格变动。
        //SUBSCRIPTION_DEFERRED - 订阅的续订时间点已延期。
        //SUBSCRIPTION_PAUSED - 订阅已暂停。
        //SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED - 订阅暂停计划已更改。
        //SUBSCRIPTION_REVOKED - 用户在到期时间之前已撤消订阅。
        //SUBSCRIPTION_EXPIRED - 订阅已到期。

        $data = json_decode(base64_decode($string),true);
        $packageName = $data['packageName'];
        if (isset($data['subscriptionNotification'])) {
            $subscriptionId = $data['subscriptionNotification']['subscriptionId'];
            $purchaseToken = $data['subscriptionNotification']['purchaseToken'];


            //1.3. 根据解密后的内容去google接口做查询校验并发货(关键参数expiryTimeMillis)
            //根据解密后的内容去google接口做校验
            //Google文档地址
            //请求域名(Get/form):
            //https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}
            $validator =new \Google_Service_AndroidPublisher($this->client);
            $resp = $validator->purchases_subscriptions->get($packageName, $subscriptionId, $purchaseToken);

            Log::debug('新订阅人员:====================');
            Log::debug(var_export($resp,true));
            Log::debug("购买状态" . $resp->getAcknowledgementState()); //0。待确认 1. 已确认

            //1.4. 消耗该笔订单
            //Google文档地址
            //请求域名(Post/form)
            //https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}:acknowledge

            $acknowledge = new SubscriptionPurchasesAcknowledgeRequest();
            $acknowledge->developerPayload = '';  // todo 可以将我们系统的订单号、用户支付金额等存入谷歌订单里
            $resp = $validator->purchases_subscriptions->acknowledge($packageName, $subscriptionId, $purchaseToken,$acknowledge);

            Log::debug('消耗结果:====================');
            Log::debug(var_export($resp,true));

            // todo 发货

        }

    }
}