function process(User $user, array $r) { $times = unserialize($r['wp_optimizemember_paid_registration_times']); $max = max($times); foreach ($times as $level => $time) { if (!($pid = $this->_translateProduct($level))) { continue; } $bpId = Am_Di::getInstance()->productTable->load($pid)->default_billing_plan_id; $fisrtPeriod = Am_Di::getInstance()->billingPlanTable->load($bpId)->first_period; $period = new Am_Period($fisrtPeriod); $this->payment[$pid] = array('start' => sqlTime($time), 'stop' => $period->addTo(sqlTime($time))); if ($time == $max) { $lastProduct = $pid; } } $this->payment[$lastProduct]['subscr_id'] = $r['wp_optimizemember_subscr_id']; $this->user = $user; return $this->doWork(); }
function getPeriod(Invoice $invoice) { $tz = date_default_timezone_get(); date_default_timezone_set('EST5EDT'); $first_period = new Am_Period($invoice->first_period); $second_period = new Am_Period($invoice->second_period); $periods = array('1d' => 'daily', '7d' => 'weekly', '14d' => 'biweekly', '1m' => 'monthly', '2m' => 'bimonthly', '3m' => 'quarterly', '1y' => 'yearly', Am_Period::MAX_SQL_DATE => 'once'); $period = $periods[$invoice->second_period]; if (empty($period)) { Am_Di::getInstance()->errorLogTable->log("WEPAY. {$invoice->second_period} is not supported"); date_default_timezone_set($tz); throw new Am_Exception_InternalError(); } if ($invoice->rebill_times == IProduct::RECURRING_REBILLS) { date_default_timezone_set($tz); return array($period, ''); } $end = $first_period->addTo(date('Y-m-d')); for ($i = 0; $i < $invoice->rebill_times; $i++) { $end = $second_period->addTo($end); } date_default_timezone_set($tz); return array($period, $end); }
public function addAccess(Am_Event $event) { /* @var $user User */ $user = $event->getUser(); $product_ids = $this->getConfig('product_ids'); if (!$product_ids) { return; } foreach ($product_ids as $id) { $product = Am_Di::getInstance()->productTable->load($id); //calucalet access dates $invoice = Am_Di::getInstance()->invoiceRecord; $invoice->setUser($user); $invoice->add($product); $begin_date = $product->calculateStartDate(Am_Di::getInstance()->sqlDate, $invoice); $p = new Am_Period($product->getBillingPlan()->first_period); $expire_date = $p->addTo($begin_date); $access = Am_Di::getInstance()->accessRecord; $access->setForInsert(array('user_id' => $user->pk(), 'product_id' => $product->pk(), 'begin_date' => $begin_date, 'expire_date' => $expire_date, 'qty' => 1)); $access->insert(); Am_Di::getInstance()->emailTemplateTable->sendZeroAutoresponders($user, $access); } }
function addAccessAfterCreate($p_b, $user) { list($product_id, $billing_plan_id) = explode('_', $p_b); $invoice = $this->getDi()->invoiceRecord; $invoice->setUser($user); $product = $this->getDi()->productTable->load($product_id); $product->setBillingPlan($billing_plan_id); $invoice->add($product); $begin_date = $product->calculateStartDate($this->getDi()->sqlDate, $invoice); $p = new Am_Period($product->getBillingPlan()->first_period); $expire_date = $p->addTo($begin_date); $access = $this->getDi()->accessRecord; $access->begin_date = $begin_date; $access->expire_date = $expire_date; $access->user_id = $user->user_id; $access->product_id = $product_id; return $access->insert(); }
public function calculateAccessDatesAction() { $this->getDi()->authAdmin->getUser()->checkPermission('grid_access', 'insert'); $invoice = $this->getDi()->invoiceRecord; $invoice->setUser($this->getDi()->userTable->load($this->user_id)); $product = $this->getDi()->productTable->load($this->getRequest()->getParam('product_id')); $invoice->add($product); $begin_date = $product->calculateStartDate($this->getDi()->sqlDate, $invoice); $p = new Am_Period($product->getBillingPlan()->first_period); $expire_date = $p->addTo($begin_date); $this->ajaxResponse(array('begin_date' => $begin_date, 'expire_date' => $expire_date)); }
public function _process(Invoice $invoice, Am_Request $request, Am_Paysystem_Result $result) { $u = $invoice->getUser(); if (!is_null($invoice->second_period)) { $a = new Am_Paysystem_Action_Redirect($url = ($this->getConfig('testing') ? self::SANDBOX_URL : self::LIVE_URL) . '/connect/subscriptions/new'); $coef = 1; if ($invoice->second_period == Am_Period::MAX_SQL_DATE) { $interval_unit = 'month'; $interval_length = 12 * (2037 - date('Y')); } else { $second_period = new Am_Period($invoice->second_period); switch ($second_period->getUnit()) { case 'd': $interval_unit = 'day'; break; case 'm': $interval_unit = 'month'; break; case 'y': $interval_unit = 'month'; $coef = 12; break; } $interval_length = $second_period->getCount(); } $first_period = new Am_Period($invoice->first_period); $start_at = new DateTime($first_period->addTo(date('Y-m-d')), new DateTimeZone('UTC')); $payment_details = array('amount' => $invoice->second_total, 'interval_length' => $interval_length * $coef, 'interval_unit' => $interval_unit, 'name' => $invoice->getLineDescription(), 'start_at' => $start_at->format('Y-m-d\\TH:i:s\\Z')); if ($invoice->rebill_times != IProduct::RECURRING_REBILLS) { $payment_details['interval_count'] = $invoice->rebill_times; } if (doubleval($invoice->first_total) > 0) { $payment_details['setup_fee'] = $invoice->first_total; } } else { $a = new Am_Paysystem_Action_Redirect($url = ($this->getConfig('testing') ? self::SANDBOX_URL : self::LIVE_URL) . '/connect/bills/new'); $payment_details = array('amount' => $invoice->first_total, 'name' => $invoice->getLineDescription()); } $user_details = array('first_name' => $u->name_f, 'last_name' => $u->name_l, 'email' => $u->email); $payment_details['merchant_id'] = $this->getConfig('merchant_id'); ksort($payment_details); ksort($user_details); if (is_null($invoice->second_period)) { foreach ($payment_details as $v => $k) { $a->__set("bill[{$v}]", $k); } foreach ($user_details as $v => $k) { $a->__set("bill[user][{$v}]", $k); } } $a->cancel_uri = $this->getCancelUrl(); $a->client_id = $this->getConfig('app_id'); $a->nonce = $this->generate_nonce(); $a->redirect_uri = $this->getDi()->config->get('root_url') . "/payment/gocardless/thanks"; $a->state = $invoice->public_id; if (!is_null($invoice->second_period)) { foreach ($payment_details as $v => $k) { $a->__set("subscription[{$v}]", $k); } foreach ($user_details as $v => $k) { $a->__set("subscription[user][{$v}]", $k); } } $date = new DateTime(null, new DateTimeZone('UTC')); $a->timestamp = $date->format('Y-m-d\\TH:i:s\\Z'); $url = parse_url($a->getUrl()); $a->signature = hash_hmac('sha256', $url['query'], $this->getConfig('app_secret')); $result->setAction($a); }
/** * @access protected */ function updateRebillDate() { $date = null; $c = $this->getPaymentsCount(); if ($this->first_total <= 0) { $c++; } // first period is "fake" because it was free trial //if ($c < $this->getExpectedPaymentsCount()) // not yet done with rebills if ($this->rebill_times > $c - 1) { // we count starting from first payment date, we rely on tm_started field here if ($this->first_total <= 0) { list($date, ) = explode(' ', $this->tm_started); } else { $date = $this->getAdapter()->selectCell("SELECT MIN(dattm) FROM ?_invoice_payment WHERE invoice_id=?d", $this->invoice_id); } $date = date('Y-m-d', strtotime($date)); $period1 = new Am_Period($this->first_period); $date = $period1->addTo($date); $period2 = new Am_Period($this->second_period); for ($i = 1; $i < $c; $i++) { $date = $period2->addTo($date); } } $this->updateQuick('rebill_date', $date); $this->rebill_date = $date; }
/** * Add access period for current product based on information from incoming paysystem transaction * @throws Am_Exception_Db_NotUnique */ public function addAccessPeriod($isFirstPayment, Invoice $invoice, Am_Paysystem_Transaction_Abstract $transaction, $beginDate, $invoicePaymentId) { if ($this->item_type != 'product') { return; } // if that is not a product then no access $a = $this->getDi()->accessRecord; $a->setDisableHooks(true); $a->begin_date = $beginDate; $p = new Am_Period($isFirstPayment ? $this->first_period : $this->second_period); $a->invoice_id = $this->invoice_id; $recurringType = $transaction->getPlugin()->getRecurringType(); if (in_array($recurringType, array(Am_Paysystem_Abstract::REPORTS_EOT, Am_Paysystem_Abstract::REPORTS_NOTHING))) { $a->expire_date = Am_Period::RECURRING_SQL_DATE; } else { $a->expire_date = $p->addTo($a->begin_date); } $a->product_id = $this->item_id; $a->user_id = $invoice->user_id; $a->transaction_id = $transaction->getUniqId(); $a->invoice_payment_id = $invoicePaymentId; $a->insert(); }
/** * Create account in aMember for user who is logged in facebook. */ function createAccount() { /* Search for account by email address */ $user = $this->getDi()->userTable->findFirstByEmail($this->getFbProfile('email')); if (empty($user)) { // Create account for user; $user = $this->getDi()->userRecord; $user->email = $this->getFbProfile('email'); $user->name_f = $this->getFbProfile('first_name'); $user->name_l = $this->getFbProfile('last_name'); $user->generateLogin(); $user->generatePassword(); $user->insert(); } $user->data()->set(self::FACEBOOK_UID, $this->getFbProfile('id'))->update(); if ($product_id = $this->getConfig('add_access')) { $product = $this->getDi()->productTable->load($product_id); $billingPlan = $this->getDi()->billingPlanTable->load($product->default_billing_plan_id); $access = $this->getDi()->accessRecord; $access->product_id = $product_id; $access->begin_date = $this->getDi()->sqlDate; $period = new Am_Period($billingPlan->first_period); $access->expire_date = $period->addTo($access->begin_date); $access->user_id = $user->pk(); $access->insert(); } return $user; }
/** * Add period to rebill_date; * If current rebill_date is null or is in the past , script will use today's date(function will be executed only when payment is added to system). So next rebill date should be set to rebill_date + payment_period; * When second parameter ($date) will be passed, it will be used instead of rebill_date in order to handle prorated access situations. * * @param type $isFirst period that will be added; * @param type $date - date that will be used instead of current rebill_date setting; * */ function addToRebillDate($isFirst, $date = null) { // If we are done with rebills just set date to null; if ($this->getPaymentsCount() >= $this->getExpectedPaymentsCount()) { $this->updateQuick('rebill_date', null); $this->rebill_date = null; return; } $today = $this->getDi()->dateTime->format('Y-m-d'); // Handle situation when customer try to rebill outdated payments; // In this situation rebill_date should be set to today. if (is_null($this->rebill_date) || $this->rebill_date < $today) { $this->rebill_date = $today; } if (!is_null($date)) { $this->rebill_date = $date; } $period = new Am_Period($isFirst ? $this->first_period : $this->second_period); $this->rebill_date = $period->addTo($this->rebill_date); $this->updateSelectedFields('rebill_date'); }
/** * @param InvoiceItem $old * @param InvoiceItem $new * @return float old_price / new_price */ function compareDayCost(InvoiceItem $old, InvoiceItem $new) { // calculate difference in money // if both products have second_period we can compare prices $k = 1.0; foreach (array('second_', 'first_') as $k) { $period_o = $old->get($k . 'period'); $period_n = $new->get($k . 'period'); $price_o = (double) $old->get($k . 'price'); $price_n = (double) $new->get($k . 'price'); if (!$price_n || !$price_o || !$period_o || !$period_n) { continue; } if ($period_o == $period_n) { return round($price_o / $price_n, 4); } // else we need to recalculate both periods to days $po = new Am_Period($period_o); $pn = new Am_Period($period_n); $days_o = strtotime($po->addTo('2012-04-01') . ' 00:00:00') - strtotime('2012-04-01 00:00:00'); $days_o = intval($days_o / (3600 * 24)); $days_n = strtotime($pn->addTo('2012-04-01') . ' 00:00:00') - strtotime('2012-04-01 00:00:00'); $days_n = intval($days_n / (3600 * 24)); $price_o /= $days_o; $price_n /= $days_n; return round($price_o / $price_n, 4); } }
public function handleRecord($id, $record) { switch ($this->_vars['action']) { case 'access': switch ($this->_vars['access_type']) { case 'exact': $begin_date = $this->_vars['begine_date']; $expire_date = $this->_vars['expire_date']; break; case 'period': $invoice = $this->grid->getDi()->invoiceRecord; $invoice->setUser($this->grid->getDi()->userTable->load($id)); $product = $this->grid->getDi()->productTable->load($this->_vars['product_id']); $begin_date = $product->calculateStartDate($this->grid->getDi()->sqlDate, $invoice); $p = new Am_Period($this->_vars['period']); $expire_date = $p->addTo($begin_date); break; } $a = $this->grid->getDi()->accessRecord; $a->begin_date = $begin_date; $a->expire_date = $expire_date; $a->product_id = $this->_vars['product_id']; $a->user_id = $id; $a->comment = $this->_vars['comment']; $a->insert(); break; case 'payment': $invoice = $this->grid->getDi()->invoiceRecord; $invoice->user_id = $id; $invoice->add($this->grid->getDi()->productTable->load($this->_vars['product_id'])); $items = $invoice->getItems(); $item = $items[0]; $item->first_price = $item->first_total = $this->_vars['amount']; $item->second_price = $item->second_total = 0; $item->rebill_times = 0; $item->second_period = null; $invoice->first_subtotal = $invoice->first_total = $this->_vars['amount']; $invoice->second_subtotal = $invoice->second_total = 0; $invoice->rebill_times = 0; $invoice->second_period = null; $invoice->first_period = $item->first_period; $invoice->paysys_id = $this->_vars['paysys_id']; $invoice->comment = $this->_vars['comment'] ? $this->_vars['comment'] : 'mass-subscribe'; $invoice->save(); $tr = new Am_Paysystem_Transaction_Manual($this->grid->getDi()->plugins_payment->loadGet($invoice->paysys_id)); $tr->setAmount($this->_vars['amount']); $tr->setTime(new DateTime($this->_vars['dattm'])); $tr->setReceiptId('mass-subscribe-' . uniqid() . '-' . $invoice->pk()); $invoice->addPayment($tr); break; } }
public function validateSource() { // We "complete" the request by acknowledging that specific user $response = $this->_sendRequest('/redirect_flows/' . $this->getUniqId() . '/actions/complete', array('data' => array('session_token' => Zend_Session::getId()))); if ($response->getStatus() !== 200) { return false; } $response = json_decode($response->getBody(), true); if (!(isset($response['redirect_flows']) && isset($response['redirect_flows']['links']) && isset($response['redirect_flows']['links']['mandate']))) { return false; } $invoice = $this->loadInvoice($this->findInvoiceId()); $mandateId = $response['redirect_flows']['links']['mandate']; $this->_updateInvoice('mandate', $mandateId); if (!empty($invoice->rebill_times) && intval($invoice->rebill_times) > 0) { // First payment is made outside the subscription, right away (one off payment): $paymentParams = array('payments' => array('currency' => $invoice->currency, 'amount' => intval(floatval($invoice->first_total) * 100), 'description' => $invoice->getLineDescription(), 'metadata' => array('user' => $invoice->getEmail(), 'invoice_id' => $invoice->public_id), 'links' => array('mandate' => $mandateId))); // One time payment of first_total $response = $this->_sendRequest('/payments', $paymentParams); if ($response->getStatus() !== 201) { return false; } $response = json_decode($response->getBody(), true); $invoice->addPayment(new Am_Paysystem_Transaction_Gocardlesspro_Payment($this->getPlugin(), $response['payments'], $this->response, $this->invokeArgs)); // Start subscription at interval + n $first_period = new Am_Period($invoice->first_period); $date_period = new DateTime($first_period->addTo(date('Y-m-d')), new DateTimeZone('UTC')); // Subscription of second_total $subscriptionParams = array('start_at' => $date_period->format('Y-m-d'), 'links' => array('mandate' => $mandateId), 'metadata' => array('user' => $invoice->getEmail(), 'invoice_id' => $invoice->public_id)); $period = empty($invoice->second_period) ? $invoice->first_period : $invoice->second_period; if ($period === Am_Period::MAX_SQL_DATE) { $subscriptionParams['interval_unit'] = 'yearly'; } else { $am_period = new Am_Period($period); switch ($am_period->getUnit()) { case 'm': $interval_unit = 'monthly'; break; case 'y': $interval_unit = 'yearly'; break; } $subscriptionParams['interval_unit'] = $interval_unit; } if (!empty($invoice->second_total)) { $subscriptionParams['amount'] = intval(floatval($invoice->second_total) * 100); } else { $subscriptionParams['amount'] = intval(floatval($invoice->first_total) * 100); } $subscriptionParams['name'] = $invoice->getLineDescription(); $subscriptionParams['currency'] = $invoice->currency; $subscriptionParams['count'] = intval($invoice->rebill_times); if ($subscriptionParams['count'] > 1000) { $subscriptionParams['count'] = 1000; } if ($subscriptionParams['interval_unit'] === 'monthly') { $subscriptionParams['day_of_month'] = 5; } $response = $this->_sendRequest('/subscriptions', array('subscriptions' => $subscriptionParams)); if ($response->getStatus() !== 201) { return false; } $response = json_decode($response->getBody(), true); $this->_updateInvoice('subscription', $response['subscriptions']['id']); } else { // One time payment only $paymentParams = array('payments' => array('currency' => $invoice->currency, 'amount' => intval(floatval($invoice->first_total) * 100), 'description' => $invoice->getLineDescription(), 'metadata' => array('user' => $invoice->getEmail(), 'invoice_id' => $invoice->public_id), 'links' => array('mandate' => $mandateId))); // One time payment of first_total $response = $this->_sendRequest('/payments', $paymentParams); if ($response->getStatus() !== 201) { return false; } $response = json_decode($response->getBody(), true); $invoice->addPayment(new Am_Paysystem_Transaction_Gocardlesspro_Payment($this->getPlugin(), $response['payments'], $this->response, $this->invokeArgs)); } $invoice->updateStatus(); return true; }
function doWork() { $user = $this->user; foreach ($this->groups as $oid => $list) { // Create new invoice; $invoice = $this->getDi()->invoiceRecord; $invoice->user_id = $this->user->pk(); foreach ($this->db_drupal->selectPage($total, "select pid, qty from ?_ms_order_products op left join ?_ms_products_plans p on op.id = p.sku where oid=?", $oid) as $row) { $invoice->add($product = $this->getDi()->productTable->findFirstByData('dms:id', $row['pid']), $row['qty']); } $invoice->calculate(); $invoice->tm_added = date('Y-m-d H:i:s', $list[0]['order_created']); $invoice->tm_started = date('Y-m-d H:i:s', $list[0]['created']); $invoice->public_id = $list[0]['order_key']; switch ($list[0]['gateway']) { case "ms_paypal_wps": $invoice->paysys_id = 'paypal'; break; default: $invoice->paysys_id = 'free'; } switch ($list[0]['order_status']) { case 'completed': $invoice->status = Invoice::PAID; break; case 'active': $invoice->status = Invoice::RECURRING_ACTIVE; break; case 'cancelled': $invoice->status = Invoice::RECURRING_CANCELLED; $invoice->tm_cancelled = date('Y-m-d H:i:s', $list[0]['order_modified']); break; default: $invoice->status = Invoice::PENDING; break; } $invoice->data()->set('dms:id', $oid); $invoice->insert(); foreach ($list as $rec) { switch ($rec['type']) { case 'cart': case 'rec_signup': case 'rec_payment': if ($rec['amount'] > 0) { // Add payment record; $payment = $this->getDi()->invoicePaymentRecord; $payment->amount = $rec['amount']; $payment->currency = $rec['currency']; $payment->dattm = date('Y-m-d H:i:s', $rec['created']); $payment->invoice_id = $invoice->pk(); $payment->paysys_id = $invoice->paysys_id; $payment->receipt_id = $rec['transaction']; $payment->transaction_id = sprintf('import-%s', $payment->receipt_id); $payment->user_id = $user->pk(); $payment->insert(); } else { $payment = null; } // Insert Access; $access = $this->getDi()->accessRecord; $access->user_id = $user->pk(); $access->setDisableHooks(); $access->begin_date = date('Y-m-d', $rec['created']); $p = new Am_Period($invoice->first_period); $access->expire_date = $p->addTo($access->begin_date); $access->invoice_id = $invoice->pk(); if (!is_null($payment)) { $access->invoice_payment_id = $payment->pk(); } $access->product_id = $product->pk(); $access->insert(); break; case 'refund': $refund = $this->getDi()->invoiceRefundRecord; $refund->invoice_id = $invoice->pk(); $refund->user_id = $user->pk(); $refund->paysys_id = $invoice->paysys_id; $refund->receipt_id = $refund->transaction_id = $rec['transaction']; $refund->dattm = date('Y-m-d H:i:s', $rec['created']); $refund->currency = $rec['currency']; $refund->amount = $rec['amount']; $refund->insert(); break; } } } $this->user->checkSubscriptions(); }