/** * Process ipn of subscription transaction * * @param Payment_Model_Order $order * @param Engine_Payment_Ipn $ipn */ public function onSubscriptionTransactionIpn(Payment_Model_Order $order, Engine_Payment_Ipn $ipn) { // Check that gateways match if ($order->gateway_id != $this->_gatewayInfo->gateway_id) { throw new Engine_Payment_Plugin_Exception('Gateways do not match'); } // Get related info $user = $order->getUser(); $subscription = $order->getSource(); $package = $subscription->getPackage(); // Get IPN data $rawData = $ipn->getRawData(); // Get tx table $transactionsTable = Engine_Api::_()->getDbtable('transactions', 'payment'); // Chargeback -------------------------------------------------------------- if (!empty($rawData['case_type']) && $rawData['case_type'] == 'chargeback') { $subscription->onPaymentFailure(); // or should we use pending? } else { if (!empty($rawData['txn_type'])) { switch ($rawData['txn_type']) { // @todo see if the following types need to be processed: // — adjustment express_checkout new_case case 'express_checkout': // Only allowed for one-time if ($package->isOneTime()) { switch ($rawData['payment_status']) { case 'Created': // Not sure about this one // Not sure about this one case 'Pending': // @todo this might be redundant // Get benefit setting $giveBenefit = Engine_Api::_()->getDbtable('transactions', 'payment')->getBenefitStatus($user); if ($giveBenefit) { $subscription->onPaymentSuccess(); } else { $subscription->onPaymentPending(); } break; case 'Completed': case 'Processed': case 'Canceled_Reversal': // Not sure about this one $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_active', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Denied': case 'Failed': case 'Voided': case 'Reversed': $subscription->onPaymentFailure(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_overdue', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Refunded': $subscription->onRefund(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_refunded', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Expired': // Not sure about this one $subscription->onExpiration(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_expired', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; default: throw new Engine_Payment_Plugin_Exception(sprintf('Unknown IPN ' . 'payment status %1$s', $rawData['payment_status'])); break; } } break; // Recurring payment was received // Recurring payment was received case 'recurring_payment': if (!$package->isOneTime()) { $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_recurrence', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } } break; // Profile was created // Profile was created case 'recurring_payment_profile_created': if (!empty($rawData['initial_payment_status']) && $rawData['initial_payment_status'] == 'Completed' || !empty($rawData['profile_status']) && $rawData['profile_status'] == 'Active') { //$subscription->active = true; $subscription->onPaymentSuccess(); // @todo add transaction row for the initial amount? // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_active', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } } else { throw new Engine_Payment_Plugin_Exception(sprintf('Unknown or missing ' . 'initial_payment_status %1$s', @$rawData['initial_payment_status'])); } break; // Profile was cancelled // Profile was cancelled case 'recurring_payment_profile_cancel': $subscription->onCancel(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_cancelled', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; // Recurring payment expired // Recurring payment expired case 'recurring_payment_expired': if (!$package->isOneTime()) { $subscription->onExpiration(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_expired', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } } break; // Recurring payment failed // Recurring payment failed case 'recurring_payment_skipped': case 'recurring_payment_suspended_due_to_max_failed_payment': case 'recurring_payment_outstanding_payment_failed': case 'recurring_payment_outstanding_payment': $subscription->onPaymentFailure(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_overdue', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; // What is this? // What is this? default: throw new Engine_Payment_Plugin_Exception(sprintf('Unknown IPN ' . 'type %1$s', $rawData['txn_type'])); break; } } else { if (!empty($rawData['payment_status'])) { switch ($rawData['payment_status']) { case 'Created': // Not sure about this one // Not sure about this one case 'Pending': // Get benefit setting $giveBenefit = Engine_Api::_()->getDbtable('transactions', 'payment')->getBenefitStatus($user); if ($giveBenefit) { $subscription->onPaymentSuccess(); } else { $subscription->onPaymentPending(); } break; case 'Completed': case 'Processed': case 'Canceled_Reversal': // Not sure about this one $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_active', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Denied': case 'Failed': case 'Voided': case 'Reversed': $subscription->onPaymentFailure(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_overdue', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Refunded': $subscription->onRefund(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_refunded', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'Expired': // Not sure about this one $subscription->onExpiration(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_expired', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; default: throw new Engine_Payment_Plugin_Exception(sprintf('Unknown IPN ' . 'payment status %1$s', $rawData['payment_status'])); break; } } else { throw new Engine_Payment_Plugin_Exception(sprintf('Unknown IPN ' . 'data structure')); } } } return $this; }
/** * Process ipn of subscription transaction * * @param Payment_Model_Order $order * @param Engine_Payment_Ipn $ipn */ public function onSubscriptionTransactionIpn(Payment_Model_Order $order, Engine_Payment_Ipn $ipn) { // Check that gateways match if ($order->gateway_id != $this->_gatewayInfo->gateway_id) { throw new Engine_Payment_Plugin_Exception('Gateways do not match'); } // Get related info $user = $order->getUser(); $subscription = $order->getSource(); $package = $subscription->getPackage(); // Get IPN data $rawData = $ipn->getRawData(); // Get tx table $transactionsTable = Engine_Api::_()->getDbtable('transactions', 'payment'); // Update subscription $subscriptionUpdated = false; if (!empty($rawData['sale_id']) && empty($subscription->gateway_profile_id)) { $subscriptionUpdated = true; $subscription->gateway_profile_id = $rawData['sale_id']; } if (!empty($rawData['invoice_id']) && empty($subscription->gateway_transaction_id)) { $subscriptionUpdated = true; $subscription->gateway_profile_id = $rawData['invoice_id']; } if ($subscriptionUpdated) { $subscription->save(); } // switch message_type switch ($rawData['message_type']) { case 'ORDER_CREATED': case 'FRAUD_STATUS_CHANGED': case 'INVOICE_STATUS_CHANGED': // Check invoice and fraud status if (strtolower($rawData['invoice_status']) == 'declined' || strtolower($rawData['fraud_status']) == 'fail') { // Payment failure $subscription->onPaymentFailure(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_overdue', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } } else { if (strtolower($rawData['fraud_status']) == 'wait') { // This is redundant, the same thing is done upon return /* // Get benefit setting $giveBenefit = Engine_Api::_()->getDbtable('transactions', 'payment')->getBenefitStatus($user); if( $giveBenefit ) { $subscription->onPaymentSuccess(); } else { $subscription->onPaymentPending(); } * */ } else { // Payment Success $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_active', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } } } break; case 'REFUND_ISSUED': // Payment Refunded $subscription->onRefund(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_refunded', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'RECURRING_INSTALLMENT_SUCCESS': $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_recurrence', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'RECURRING_INSTALLMENT_FAILED': $subscription->onPaymentFailure(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_overdue', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'RECURRING_STOPPED': $subscription->onCancel(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_cancelled', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; case 'RECURRING_COMPLETE': $subscription->onExpiration(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_expired', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } break; /* case 'RECURRING_RESTARTED': break; * */ /* case 'RECURRING_RESTARTED': break; * */ default: throw new Engine_Payment_Plugin_Exception(sprintf('Unknown IPN ' . 'type %1$s', $rawData['message_type'])); break; } return $this; }
/** * Process return of subscription transaction * * @param Payment_Model_Order $order * @param array $params */ public function onSubscriptionTransactionReturn(Payment_Model_Order $order, array $params = array()) { // Check that gateways match if ($order->gateway_id != $this->_gatewayInfo->gateway_id) { throw new Engine_Payment_Plugin_Exception('Gateways do not match'); } // Get related info $user = $order->getUser(); $subscription = $order->getSource(); $package = $subscription->getPackage(); // Check subscription state if ($subscription->status == 'active' || $subscription->status == 'trial') { return 'active'; } else { if ($subscription->status == 'pending') { return 'pending'; } } // Let's log it $this->getGateway()->getLog()->log('Return: ' . print_r($params, true), Zend_Log::INFO); // Should we accept this? // Update order with profile info and complete status? $order->state = 'complete'; $order->gateway_order_id = 0; // Hack $order->save(); // Insert transaction $transactionsTable = Engine_Api::_()->getDbtable('transactions', 'payment'); $transactionsTable->insert(array('user_id' => $order->user_id, 'gateway_id' => $this->_gatewayInfo->gateway_id, 'timestamp' => new Zend_Db_Expr('NOW()'), 'order_id' => $order->order_id, 'type' => 'payment', 'state' => 'okay', 'gateway_transaction_id' => crc32(microtime() . $order->order_id), 'amount' => $package->price, 'currency' => $this->getGateway()->getCurrency())); // Get benefit setting $giveBenefit = Engine_Api::_()->getDbtable('transactions', 'payment')->getBenefitStatus($user); $giveBenefit = true; // Need this // Enable now if ($giveBenefit) { // Update subscription $subscription->gateway_id = $this->_gatewayInfo->gateway_id; $subscription->gateway_profile_id = crc32(time() . $order->order_id); // Hack $subscription->onPaymentSuccess(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_active', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } return 'active'; } else { // Update subscription $subscription->gateway_id = $this->_gatewayInfo->gateway_id; $subscription->gateway_profile_id = crc32(time() . $order->order_id); // Hack $subscription->onPaymentPending(); // send notification if ($subscription->didStatusChange()) { Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_subscription_pending', array('subscription_title' => $package->title, 'subscription_description' => $package->description, 'subscription_terms' => $package->getPackageDescription(), 'object_link' => 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array(), 'user_login', true))); } return 'pending'; } }