dzenlife
3/31/2020 - 8:31 AM

apple subscription

<?
//google play
const PAYMENT_PACKAGE_NAME = 'ru.my';
const PAYMENT_SUBSCRIPTION_ID = 'ru.my.sub';
const PAYMENT_SUBSCRIPTION_YEAR_ID = 'ru.my.sub_year';
const SUBSCRIPTION_RENEWED = 2;
const SUBSCRIPTION_RECOVERED = 1;
const SUBSCRIPTION_CANCELED = 3;
const SUBSCRIPTION_PURCHASED = 4;
const SUBSCRIPTION_REVOKED = 12;
const SUBSCRIPTION_EXPIRED = 13;
const SUBSCRIPTION_ON_HOLD = 5;
const SUBSCRIPTION_RESTARTED = 7;
//appstore
const APPSTORE_MODE = 'prod';
const APPSTORE_SERVER_DEV = 'https://sandbox.itunes.apple.com/verifyReceipt';
const APPSTORE_SERVER_PROD = 'https://buy.itunes.apple.com/verifyReceipt';
const APPSTORE_PASSWORD = 'pass';
const APPSTORE_BID = 'ru.my';
const APPSTORE_PRODUCT_MONTH_ID = 'ru.my.submonth';
const APPSTORE_PRODUCT_YEAR_ID = 'ru.my.subyear';
//appstore subscription
const IOS_SUB_INITIAL_BUY = 'INITIAL_BUY';
const IOS_SUB_CANCEL = 'CANCEL';
const IOS_SUB_DID_CHANGE_RENEWAL_STATUS = 'DID_CHANGE_RENEWAL_STATUS';
const IOS_SUB_RENEWAL = 'RENEWAL';
const IOS_SUB_INTERACTIVE_RENEWAL = 'INTERACTIVE_RENEWAL';
const IOS_SUB_DID_CHANGE_RENEWAL_PREF = 'DID_CHANGE_RENEWAL_PREF';
const IOS_DID_RECOVER = 'DID_RECOVER';

function updateStatusAppleSubscribe($data) {
    $this->notificationType = $data->notification_type;
    $this->status_subscription = $this->getStatusSubscription();
    $this->data = $data;
    $this->apple_transaction_id = $data->latest_receipt_info->original_transaction_id;

    $user = $this->getByFieldValue('apple_transaction_id', $this->apple_transaction_id);
    $this->appleReceipt = $user['apple_receipt'];

    $info = array(
        'status' => 0,
        'product_id' => $data->latest_receipt_info->product_id,
        'bid' => $data->latest_receipt_info->bid,
    );

    $this->dataLog = [
        'errorText' => 'updateStatusAppleSubscribe',
        'error' => 230,
    ];

    if ($user && $this->checkAppleInfo($info) && $this->verifyAppleToken()) {
        $query = "UPDATE `user` SET status_subscription=$this->status_subscription WHERE apple_transaction_id = '$this->apple_transaction_id'";
        $stmt = $this->conn->prepare($query);

        $this->dataLog = [
            $query,
            'error' => 0,
        ];

        if (!$stmt->execute()) {
            $this->dataLog['error'] = 230;
        }
    }

    __log($this->dataLog, '/logs/subsciption_handler_ios.log');
}

function getStatusSubscription() {
    switch ($this->notificationType) {
        case self::SUBSCRIPTION_RENEWED:
        case self::SUBSCRIPTION_RECOVERED:
        case self::SUBSCRIPTION_PURCHASED:
        case self::SUBSCRIPTION_RESTARTED:
        case self::IOS_SUB_DID_CHANGE_RENEWAL_PREF:
        case self::IOS_SUB_DID_CHANGE_RENEWAL_STATUS:
        case self::IOS_SUB_INITIAL_BUY:
        case self::IOS_SUB_INTERACTIVE_RENEWAL:
        case self::IOS_SUB_RENEWAL:
        case self::DID_RECOVER:
            return 1;
            break;
        case self::SUBSCRIPTION_REVOKED:
        case self::SUBSCRIPTION_EXPIRED:
        case self::SUBSCRIPTION_ON_HOLD:
        case self::IOS_SUB_CANCEL:
            return 0;
            break;
        default:
            return 0;
            break;
    }
}

function checkAppleInfo($infoArray) {
    if ($infoArray['product_id'] != self::APPSTORE_PRODUCT_MONTH_ID && $infoArray['product_id'] != self::APPSTORE_PRODUCT_YEAR_ID) {
        return false;
    }

    if ($infoArray['bid'] != self::APPSTORE_BID) {
        return false;
    }

    if ($infoArray['status'] != 0) {
        return false;
    }

    return true;
}

function verifyAppleToken() {
    $this->paymentAppleInit();

    $ch = curl_init($this->url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($this->postData));

    $response = curl_exec($ch);
    $errno = curl_errno($ch);
    $errmsg = curl_error($ch);
    curl_close($ch);

    __log([json_decode($response), $errno, $errmsg], '/logs/payment_apple.log');

    if ($errno != 0) {
        return false;
    }

    $data = json_decode($response);
    if (!is_object($data)) {
        return false;
    }

    if (!isset($data->status) || $data->status != 0) {
        $this->dataLog['error'] = $data->status;
        return false;
    }

    $latest_receipt_info = $data->latest_receipt_info[0];
    $info = array(
        'status' => $data->status,
        'product_id' => $latest_receipt_info->product_id,
        'bid' => isset($data->receipt->bundle_id) ? $data->receipt->bundle_id : $data->receipt->bid,
    );

    $this->apple_transaction_id = $latest_receipt_info->original_transaction_id;
    $this->apple_expires_date = $latest_receipt_info->expires_date_ms / 1000;
    $this->status_subscription = date('Y-m-d H:i:s', $this->apple_expires_date) > date('Y-m-d H:i:s');

    if ($this->checkAppleInfo($info)) {
        return true;
    } else {
        return false;
    }
}

function paymentAppleInit() {
    $this->postData = [
        'receipt-data' => $this->appleReceipt,
        'password' => self::APPSTORE_PASSWORD,
        'exclude-old-transactions' => true,
    ];

    switch (self::APPSTORE_MODE) {
        case 'dev':
            $this->url = self::APPSTORE_SERVER_DEV;
            break;
        case 'prod':
            $this->url = self::APPSTORE_SERVER_PROD;
            break;
    }
}
<?
$arrSql = [
    'SELECT' => 'id',
    'FROM' => 'user',
    'WHERE' => "DATE_ADD(CURDATE(), INTERVAL -1 DAY) > apple_expires_date AND apple_expires_date!='0000:00:00 00:00:00' AND status_subscription = 1", 
];

$modelQuery = new MySqlBase();
$modelQuery->initSqlQuery($arrSql);
$modelQuery->run();
$modelQuery->getIds();

if ($modelQuery->userIds) {
    $modelQuery->cancelStatus();
}
................................
public function cancelStatus() {
  foreach ($this->userIds as $id) {
      $query = "UPDATE `user` SET status_subscription=0 WHERE id = {$id}";
      $log = [
          $query,
          'error' => 0,
      ];

      $user = User::getById($id, 'apple_expires_date, apple_receipt');

      $userModel = new User($this->db);
      $userModel->appleReceipt = $user['apple_receipt'];
      $userModel->id = $id;
      $userModel->verifyAppleToken();

      $formatExpiresDate = date('Y-m-d H:i:s', $userModel->apple_expires_date);
      $isRenewal = $user['apple_expires_date'] < $formatExpiresDate;

      if ($isRenewal) {
          $userModel->fields[] = "apple_expires_date='$formatExpiresDate'";
          if (!$userModel->update()) {
              $log['error'] = 'errorUpdate';
          }
      } else {
          $stmt = $this->db->prepare($query);

          if (!$stmt->execute()) {
              $log['error'] = 230;
          }
      }

      __log($log, '/logs/cron_subscription_ios_cancel.log');
  }
}