119 lines
3.5 KiB
PHP
119 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\UserSubscriber;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class AppMarketPurchaseVerifier
|
|
{
|
|
public function verifyBazaarSubscription(string $subscriptionId, string $purchaseToken): ?Carbon
|
|
{
|
|
$packageName = config('services.app_markets.package_name');
|
|
$url = "https://pardakht.cafebazaar.ir/devapi/v2/api/applications/{$packageName}/subscriptions/{$subscriptionId}/purchases/{$purchaseToken}";
|
|
|
|
$response = Http::timeout(3)->connectTimeout(2)->withHeaders([
|
|
'CAFEBAZAAR-PISHKHAN-API-SECRET' => config('services.app_markets.bazaar_secret'),
|
|
])->get($url);
|
|
|
|
|
|
if (!$response->successful()) {
|
|
Log::error('Failed to verify Bazaar subscription', [
|
|
'status' => $response->status(),
|
|
'body' => $response->body(),
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
|
|
$validUntil = $response->json('validUntilTimestampMsec');
|
|
|
|
if (!$validUntil || $validUntil < now()->timestamp * 1000) {
|
|
return null;
|
|
}
|
|
|
|
return Carbon::createFromTimestampMs($validUntil);
|
|
}
|
|
|
|
public function refreshBazaarSubscriber(UserSubscriber $subscriber): bool
|
|
{
|
|
if (!$subscriber->subscription_id || !$subscriber->purchase_token) {
|
|
return false;
|
|
}
|
|
|
|
$expiredAt = $this->verifyBazaarSubscription($subscriber->subscription_id, $subscriber->purchase_token);
|
|
|
|
if (!$expiredAt) {
|
|
$subscriber->update(['expired_at' => now()]);
|
|
|
|
return false;
|
|
}
|
|
|
|
$subscriber->update([
|
|
'expired_at' => $expiredAt,
|
|
'last_verified_at' => now(),
|
|
]);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function verifyMyketProduct(string $skuId, string $token): ?array
|
|
{
|
|
$packageName = config('services.app_markets.package_name');
|
|
$url = "https://developer.myket.ir/api/partners/applications/{$packageName}/purchases/products/{$skuId}/verify";
|
|
|
|
$response = Http::timeout(3)->connectTimeout(2)->withHeaders([
|
|
'X-Access-Token' => config('services.app_markets.myket_access_token'),
|
|
])->post($url, [
|
|
'tokenId' => $token,
|
|
]);
|
|
|
|
if (!$response->successful()) {
|
|
Log::error('Failed to verify Myket purchase', [
|
|
'status' => $response->status(),
|
|
'body' => $response->body(),
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
|
|
$data = $response->json();
|
|
|
|
if (($data['purchaseState'] ?? null) !== 0 || empty($data['purchaseTime'])) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'data' => $data,
|
|
'purchased_at' => Carbon::createFromTimestampMs($data['purchaseTime']),
|
|
];
|
|
}
|
|
|
|
public function refreshMyketSubscriber(UserSubscriber $subscriber): bool
|
|
{
|
|
if (!$subscriber->product_id || !$subscriber->purchase_token || !$subscriber->subscribe) {
|
|
return false;
|
|
}
|
|
|
|
$purchase = $this->verifyMyketProduct($subscriber->product_id, $subscriber->purchase_token);
|
|
|
|
if (!$purchase) {
|
|
$subscriber->update(['expired_at' => now()]);
|
|
|
|
return false;
|
|
}
|
|
|
|
$expiredAt = $purchase['purchased_at']->copy()->addDays($subscriber->subscribe->expired_day);
|
|
|
|
$subscriber->update([
|
|
'purchased_at' => $purchase['purchased_at'],
|
|
'expired_at' => $expiredAt,
|
|
'last_verified_at' => now(),
|
|
]);
|
|
|
|
return $expiredAt->greaterThanOrEqualTo(now());
|
|
}
|
|
}
|