Skip to content

Commit

Permalink
Add support for multiple offer periods for Google subscription types
Browse files Browse the repository at this point in the history
remp/crm#2635
  • Loading branch information
Matus Kalafut committed Nov 14, 2022
1 parent eb282e9 commit e3f1909
Show file tree
Hide file tree
Showing 5 changed files with 541 additions and 57 deletions.
81 changes: 42 additions & 39 deletions src/Hermes/DeveloperNotificationReceivedHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Psr\Log\LoggerAwareTrait;
use ReceiptValidator\GooglePlay\Acknowledger;
use ReceiptValidator\GooglePlay\SubscriptionResponse;
use ReceiptValidator\GooglePlay\Validator;
use Tomaj\Hermes\Handler\HandlerInterface;
use Tomaj\Hermes\Handler\RetryTrait;
use Tomaj\Hermes\MessageInterface;
Expand All @@ -32,44 +33,19 @@ class DeveloperNotificationReceivedHandler implements HandlerInterface

public const INFO_LOG_LEVEL = 'google_developer_notifications';

private $developerNotificationsRepository;

private $googlePlaySubscriptionTypesRepository;

private $googlePlayValidatorFactory;

private $paymentGatewaysRepository;

private $paymentMetaRepository;

private $paymentsRepository;

private $subscriptionsRepository;

private $subscriptionMetaRepository;

private $subscriptionResponseProcessor;
private $googlePlayValidator;

public function __construct(
SubscriptionResponseProcessorInterface $subscriptionResponseProcessor,
DeveloperNotificationsRepository $developerNotificationsRepository,
GooglePlaySubscriptionTypesRepository $googlePlaySubscriptionTypesRepository,
GooglePlayValidatorFactory $googlePlayValidator,
PaymentGatewaysRepository $paymentGatewaysRepository,
PaymentMetaRepository $paymentMetaRepository,
PaymentsRepository $paymentsRepository,
SubscriptionsRepository $subscriptionsRepository,
SubscriptionMetaRepository $subscriptionMetaRepository
private SubscriptionResponseProcessorInterface $subscriptionResponseProcessor,
private DeveloperNotificationsRepository $developerNotificationsRepository,
private GooglePlaySubscriptionTypesRepository $googlePlaySubscriptionTypesRepository,
private GooglePlayValidatorFactory $googlePlayValidatorFactory,
private PaymentGatewaysRepository $paymentGatewaysRepository,
private PaymentMetaRepository $paymentMetaRepository,
private PaymentsRepository $paymentsRepository,
private SubscriptionsRepository $subscriptionsRepository,
private SubscriptionMetaRepository $subscriptionMetaRepository
) {
$this->developerNotificationsRepository = $developerNotificationsRepository;
$this->googlePlaySubscriptionTypesRepository = $googlePlaySubscriptionTypesRepository;
$this->googlePlayValidatorFactory = $googlePlayValidator;
$this->paymentGatewaysRepository = $paymentGatewaysRepository;
$this->paymentMetaRepository = $paymentMetaRepository;
$this->paymentsRepository = $paymentsRepository;
$this->subscriptionsRepository = $subscriptionsRepository;
$this->subscriptionMetaRepository = $subscriptionMetaRepository;
$this->subscriptionResponseProcessor = $subscriptionResponseProcessor;
}

public function handle(MessageInterface $message): bool
Expand All @@ -83,7 +59,7 @@ public function handle(MessageInterface $message): bool
}

// validate and load google subscription
$googlePlayValidator = $this->googlePlayValidatorFactory->create();
$googlePlayValidator = $this->googlePlayValidator ?: $this->googlePlayValidatorFactory->create();
$gSubscription = $googlePlayValidator
->setPackageName($developerNotification->package_name)
->setPurchaseToken($developerNotification->purchase_token)
Expand Down Expand Up @@ -167,6 +143,12 @@ public function handle(MessageInterface $message): bool
return true;
}

// Useful in tests
public function setGooglePlayValidator(Validator $googlePlayValidator): void
{
$this->googlePlayValidator = $googlePlayValidator;
}

private function developerNotification(MessageInterface $message): ActiveRow
{
$payload = $message->getPayload();
Expand Down Expand Up @@ -282,10 +264,17 @@ private function createPayment(SubscriptionResponse $subscriptionResponse, Activ

$recurrentCharge = true;

// Handle case when first subscription type is different from renewals.
// Note: currently, this only handles Introductory price (in Google console) of "Single payment" type, not "Recurring payment" type.
// Handle case when introductory subscription type is different from renewals.
if ($subscriptionType->next_subscription_type_id) {
$subscriptionType = $subscriptionType->next_subscription_type;
$googleSubscriptionType = $this->googlePlaySubscriptionTypesRepository->findByGooglePlaySubscriptionId($developerNotification->subscription_id);
if ($googleSubscriptionType->offer_periods) {
$usedOfferPeriods = $this->getUsedOfferPeriods($subscriptionResponse->getRawResponse()->getOrderId());
if ($usedOfferPeriods >= $googleSubscriptionType->offer_periods) {
$subscriptionType = $subscriptionType->next_subscription_type;
}
} else {
$subscriptionType = $subscriptionType->next_subscription_type;
}
}
}

Expand Down Expand Up @@ -473,4 +462,18 @@ public function processCancelReason(SubscriptionResponse $subscriptionResponse,

return $cancelData;
}

private function getUsedOfferPeriods($orderId): int
{
$matches = [];
// Order ID for renewal payments ends with '..0', e.g. 'GPA.1111-1111-1111-11111..0'
preg_match('/\.\.(\d+)$/', $orderId, $matches);

if (isset($matches[1])) {
// Renewal starts from 0; first renewal order id ends with '..0'; initial payment has no sufix
return (int)$matches[1] + 1;
}

return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ class GooglePlaySubscriptionTypesRepository extends Repository
{
protected $tableName = 'google_play_billing_subscription_types';

final public function add(string $googlePlaySubscriptionId, ActiveRow $subscriptionType)
final public function add(string $googlePlaySubscriptionId, ActiveRow $subscriptionType, ?int $offerPeriods = null)
{
return $this->getTable()->insert([
'subscription_id' => $googlePlaySubscriptionId,
'subscription_type_id' => $subscriptionType->id,
'offer_periods' => $offerPeriods,
]);
}

Expand Down
Loading

0 comments on commit e3f1909

Please sign in to comment.