Toggle navigation
Toggle navigation
This project
Loading...
Sign in
OnePoem
/
OnePoem-Server
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
李帅
2022-11-13 00:00:13 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
b73a3033fe60807be462e2ef145abdd95e382036
b73a3033
1 parent
b0d5fb41
1.使用谷歌服务账号进行验证
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
97 deletions
app/Console/Commands/DevGoogle.php
app/Http/Controllers/Controller.php
app/Payment/GooglePayment.php
app/Console/Commands/DevGoogle.php
View file @
b73a303
...
...
@@ -3,6 +3,7 @@
namespace
App\Console\Commands
;
use
App\Payment\GooglePayment
;
use
Carbon\Carbon
;
use
Illuminate\Console\Command
;
class
DevGoogle
extends
Command
...
...
@@ -38,21 +39,27 @@ class DevGoogle extends Command
*/
public
function
handle
()
{
//
// $credentials_file = public_path().'/pc-api-7482901338487549764-603-566eccf76b91.json';
// $client = new \Google_Client();
// $client->setAuthConfig($credentials_file);
// $client->setApplicationName("Client_Library_Examples");
// $client->setScopes(
// [
// \Google_Service_AndroidPublisher::ANDROIDPUBLISHER,
// ]
// );
//
// $validator =new \Google_Service_AndroidPublisher($client);
// $resp = $validator->purchases_subscriptions->get('pub.yiyan.parlando.Parlando', 'monthly_yiyan_vip', 'aa');
// dd($resp);
$credentials_file
=
public_path
()
.
'/pc-api-7482901338487549764-603-566eccf76b91.json'
;
$client
=
new
\Google_Client
();
$client
->
setAuthConfig
(
$credentials_file
);
$client
->
setApplicationName
(
"Client_Library_Examples"
);
$client
->
setScopes
(
[
\Google_Service_AndroidPublisher
::
ANDROIDPUBLISHER
,
]
);
$validator
=
new
\Google_Service_AndroidPublisher
(
$client
);
$resp
=
$validator
->
purchases_subscriptions
->
get
(
'pub.yiyan.parlando.Parlando'
,
'monthly_yiyan_vip'
,
'aa'
);
dd
(
$resp
);
$time
=
1668186646527
;
$startTime
=
1668184557316
;
echo
date
(
'Y-m-d H:i:s'
,
$startTime
/
1000
)
.
PHP_EOL
;
echo
date
(
'Y-m-d H:i:s'
,
$time
/
1000
)
.
PHP_EOL
;
echo
Carbon
::
createFromTimestampMs
(
$time
)
->
toDateTimeString
();
return
0
;
}
}
...
...
app/Http/Controllers/Controller.php
View file @
b73a303
...
...
@@ -25,6 +25,12 @@ class Controller extends BaseController
{
$ua
=
request
()
->
header
(
'user-agent'
);
return
'ios'
;
if
(
strpos
(
$ua
,
'iPhone'
)
||
strpos
(
$ua
,
'iPad'
)
||
strpos
(
$ua
,
'Mac OS X'
))
{
return
'ios'
;
}
else
if
(
strpos
(
$ua
,
'Android'
)
||
strpos
(
$ua
,
'android'
)){
return
'android'
;
}
else
{
return
'unkown'
;
}
}
}
...
...
app/Payment/GooglePayment.php
View file @
b73a303
...
...
@@ -23,6 +23,23 @@ class GooglePayment implements PaymentInterface
const
IS_SANDBOX
=
true
;
const
SUBSCRIPTION_RECOVERED
=
1
;
//- 从帐号保留状态恢复了订阅。
const
SUBSCRIPTION_RENEWED
=
2
;
// 续订了处于活动状态的订阅。
const
SUBSCRIPTION_CANCELED
=
3
;
// 自愿或非自愿地取消了订阅。如果是自愿取消,在用户取消时发送。
const
SUBSCRIPTION_PURCHASED
=
4
;
// 购买了新的订阅。
const
SUBSCRIPTION_ON_HOLD
=
5
;
// 订阅已进入帐号保留状态(如果已启用)。
const
SUBSCRIPTION_IN_GRACE_PERIOD
=
6
;
// 订阅已进入宽限期(如果已启用)。
const
SUBSCRIPTION_RESTARTED
=
7
;
// 用户已通过 Play > 帐号 > 订阅重新激活其订阅(需要选择使用订阅恢复功能)。
const
SUBSCRIPTION_PRICE_CHANGE_CONFIRMED
=
8
;
// 用户已成功确认订阅价格变动。
const
SUBSCRIPTION_DEFERRED
=
9
;
// 订阅的续订时间点已延期。
const
SUBSCRIPTION_PAUSED
=
10
;
// 订阅已暂停。
const
SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED
=
11
;
// 订阅暂停计划已更改。
const
SUBSCRIPTION_REVOKED
=
12
;
// 用户在到期时间之前已撤消订阅。
const
SUBSCRIPTION_EXPIRED
=
13
;
// 订阅已到期。
const
ONE_TIME_PRODUCT_PURCHASED
=
1
;
//用户成功购买了一次性商品。
const
ONE_TIME_PRODUCT_CANCELED
=
2
;
// 用户已取消待处理的一次性商品购买交易。
public
$client
;
public
function
__construct
()
...
...
@@ -30,8 +47,6 @@ class GooglePayment implements PaymentInterface
$this
->
client
=
$this
->
getGoogleClient
();
}
public
function
prepare
(
Order
$order
)
{
// 查询订单对应的产品id
...
...
@@ -143,100 +158,125 @@ class GooglePayment implements PaymentInterface
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 - 订阅已到期。
// 'acknowledgementState' => 1,
// 'autoRenewing' => false, // 设置是否在订阅到期时自动续订。
// 'autoResumeTimeMillis' => NULL,
// 'cancelReason' => 1, //订阅被取消或未自动续订的原因。可能的值包括:0.用户取消了订阅 1.由于结算问题 2.系统取消了订阅 2. 订阅被新的订阅取代了。3.开发者已取消订阅
// 'cancelSurveyResultType' => 'Google\\Service\\AndroidPublisher\\SubscriptionCancelSurveyResult',
// 'cancelSurveyResultDataType' => '',
// 'countryCode' => 'CA',
// 'developerPayload' => '',
// 'emailAddress' => NULL,
// 'expiryTimeMillis' => '1668023054641', // 订阅的到期时间
// 'externalAccountId' => NULL,
// 'familyName' => NULL,
// 'givenName' => NULL,
// 'introductoryPriceInfoType' => 'Google\\Service\\AndroidPublisher\\IntroductoryPriceInfo',
// 'introductoryPriceInfoDataType' => '',
// 'kind' => 'androidpublisher#subscriptionPurchase',
// 'linkedPurchaseToken' => NULL,
// 'obfuscatedExternalAccountId' => 'osnB10209503106007', //我们系统的订单号
// 'obfuscatedExternalProfileId' => NULL,
// 'orderId' => 'GPA.3390-9999-6519-16223..5',
// 'paymentState' => NULL, //订阅的付款状态。可能的值包括:0=待处理付款,1=付款已收讫,2=免费试用,3=延迟升级/降级.已取消、已过期的订阅不会显示。
// 'priceAmountMicros' => '5490000', // 订阅价格。例如,如果订阅价格为 1.99 欧元,priceAmountMicros 为 1990000。
// 'priceChangeType' => 'Google\\Service\\AndroidPublisher\\SubscriptionPriceChange',
// 'priceChangeDataType' => '',
// 'priceCurrencyCode' => 'CAD',
// 'profileId' => NULL,
// 'profileName' => NULL,
// 'promotionCode' => NULL,
// 'promotionType' => NULL,
// 'purchaseType' => 0, // 订阅的购买类型 0=测试,1=促销,当购买交易不是使用标准的应用内购买结算流程时,系统才会设置此字段。
// 'startTimeMillis' => '1668020958362',
// 'userCancellationTimeMillis' => NULL,
// 'internal_gapi_mappings' =>
$data
=
json_decode
(
base64_decode
(
$string
),
true
);
Log
::
debug
(
'返回的数据:===================='
);
Log
::
debug
(
print_r
(
$data
,
true
));
$packageName
=
$data
[
'packageName'
];
if
(
isset
(
$data
[
'subscriptionNotification'
]))
{
$subscriptionId
=
$data
[
'subscriptionNotification'
][
'subscriptionId'
];
$purchaseToken
=
$data
[
'subscriptionNotification'
][
'purchaseToken'
];
try
{
$validator
=
new
\Google_Service_AndroidPublisher
(
$this
->
client
);
$resp
=
$validator
->
purchases_subscriptions
->
get
(
$packageName
,
$subscriptionId
,
$purchaseToken
);
}
catch
(
\Exception
$exception
){
Log
::
error
(
"查询订阅出错了:=================="
);
Log
::
error
(
"packageName:"
.
$packageName
);
Log
::
error
(
"subscriptionId:"
.
$subscriptionId
);
Log
::
error
(
"purchaseToken:"
.
$purchaseToken
);
Log
::
error
(
"==============================="
);
return
false
;
}
$orderSn
=
$resp
->
getObfuscatedExternalAccountId
();
$order
=
Order
::
query
()
->
where
(
'order_sn'
,
$orderSn
)
->
first
();
if
(
!
$order
)
{
Log
::
error
(
"查无此订单"
);
return
false
;
}
switch
(
$data
[
'notificationType'
]){
case
self
::
SUBSCRIPTION_PURCHASED
:
if
(
$resp
->
getPaymentState
()
==
1
)
$order
->
status
=
Order
::
DONE
;
/** 修改订单状态*/
$order
->
pay_time
=
Carbon
::
now
();
$order
->
pay_number
=
$resp
->
getOrderId
();
$order
->
pay_type
=
$resp
->
getKind
();
$order
->
callback
=
$string
;
$order
->
save
();
/** 给用户加会员*/
$user
=
UserProfile
::
query
()
->
find
(
$order
->
user_id
);
$user
->
is_vip
=
1
;
$user
->
create_vip_time
=
Carbon
::
createFromTimestampMs
(
$resp
->
getStartTimeMillis
());
$user
->
expire_vip_time
=
Carbon
::
createFromTimestampMs
(
$resp
->
getExpiryTimeMillis
());
$user
->
buy_number
+=
1
;
$user
->
buy_amount
+=
$order
->
pay_amount
;
$user
->
last_buy_time
=
Carbon
::
now
();
$user
->
save
();
break
;
case
self
::
SUBSCRIPTION_RENEWED
:
case
self
::
SUBSCRIPTION_RESTARTED
:
/** 给用户加会员*/
$user
=
UserProfile
::
query
()
->
find
(
$order
->
user_id
);
$user
->
is_vip
=
1
;
$user
->
expire_vip_time
=
Carbon
::
createFromTimestampMs
(
$resp
->
getExpiryTimeMillis
());
$user
->
buy_number
+=
1
;
$user
->
buy_amount
+=
$order
->
pay_amount
;
$user
->
last_buy_time
=
Carbon
::
now
();
$user
->
save
();
break
;
case
self
::
SUBSCRIPTION_CANCELED
:
case
self
::
SUBSCRIPTION_EXPIRED
:
/** 给用户取消会员*/
$user
=
UserProfile
::
query
()
->
find
(
$order
->
user_id
);
$user
->
is_vip
=
0
;
$user
->
expire_vip_time
=
Carbon
::
createFromTimestampMs
(
$resp
->
getExpiryTimeMillis
());
$user
->
save
();
break
;
default
:
Log
::
debug
(
'特殊通知类型:'
.
$data
[
'notificationType'
]
.
' ===================='
);
Log
::
debug
(
var_export
(
$resp
,
true
));
}
}
elseif
(
isset
(
$data
[
'subscriptionNotification'
])){
// oneTimeProductNotification 一次性购买相关
/**
* 成功会返回返回字段解释 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] =>
* )
*/
//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 发货
$productId
=
$data
[
'OneTimeProductNotification'
][
'purchaseToken'
];
$purchaseToken
=
$data
[
'OneTimeProductNotification'
][
'purchaseToken'
];
try
{
$validator
=
new
\Google_Service_AndroidPublisher
(
$this
->
client
);
$resp
=
$validator
->
purchases_products
->
get
(
$packageName
,
$productId
,
$purchaseToken
);
}
catch
(
\Exception
$e
)
{
Log
::
error
(
"查询订阅出错了:=================="
);
Log
::
error
(
"packageName:"
.
$packageName
);
Log
::
error
(
"productId:"
.
$productId
);
Log
::
error
(
"purchaseToken:"
.
$purchaseToken
);
Log
::
error
(
"==============================="
);
return
false
;
}
// ...
switch
(
$data
[
'notificationType'
]){
case
self
::
ONE_TIME_PRODUCT_PURCHASED
:
case
self
::
ONE_TIME_PRODUCT_CANCELED
:
default
:
Log
::
debug
(
'特殊通知类型:'
.
$data
[
'notificationType'
]
.
' ===================='
);
Log
::
debug
(
var_export
(
$resp
,
true
));
break
;
}
}
else
{
Log
::
debug
(
"收到测试通知信息 version:"
.
$data
[
'testNotification'
][
'version'
]);
}
}
...
...
Please
register
or
login
to post a comment