| Current Path : /var/www/html/components/com_osmembership/plugins/ |
| Current File : /var/www/html/components/com_osmembership/plugins/os_stripe.php |
<?php
/**
* @version 2.14.1
* @package Membership Pro
* @subpackage Payment Plugins
* @author Tuan Pham Ngoc
* @copyright Copyright (C) 2012 - 2018 Ossolution Team
* @license GNU/GPL, see LICENSE.php
*/
defined('_JEXEC') or die;
class os_stripe extends MPFPayment
{
/**
* Stripe error message
*
* @var array
*/
protected $stripeErrors = [];
/**
* Constructors function
*
* @param \Joomla\Registry\Registry $params
* @param array $config
*/
public function __construct($params, $config = array('type' => 1))
{
require_once __DIR__ . '/stripe/init.php';
$document = JFactory::getDocument();
$publicKey = $params->get('stripe_public_key');
if ($params->get('use_stripe_card_element', 0))
{
$verison = OSMembershipHelper::getInstalledVersion();
if (version_compare($verison, '2.14.0', 'le'))
{
JFactory::getApplication()->enqueueMessage(JText::_('OSM_STRIPE_CARD_ELEMENET_REQUIREMENT'), 'warning');
}
$document->addScript('https://js.stripe.com/v3/');
$document->addScriptDeclaration(
" var stripe = Stripe('$publicKey');\n
var elements = stripe.elements();\n
"
);
$config['type'] = 0;
}
else
{
$document->addScript('https://js.stripe.com/v2/');
$document->addScriptDeclaration(
" var stripePublicKey = '$publicKey';\n
Stripe.setPublishableKey('$publicKey');\n
"
);
}
$this->stripeErrors = [
'invalid_number' => JText::_('OSM_STRIPE_ERROR_INVALID_NUMBER'),
'invalid_expiry_month' => JText::_('OSM_STRIPE_ERROR_INVALID_EXPIRY_MONTH'),
'invalid_expiry_year' => JText::_('OSM_STRIPE_ERROR_INVALID_EXPIRY_YEAR'),
'invalid_cvc' => JText::_('OSM_STRIPE_ERROR_INVALID_EXPIRY_CVC'),
'incorrect_number' => JText::_('OSM_STRIPE_ERROR_INVALID_NUMBER'),
'expired_card' => JText::_('OSM_STRIPE_ERROR_EXPIRED_CARD'),
'incorrect_cvc' => JText::_('OSM_STRIPE_ERROR_INCORRECT_CVC'),
'incorrect_zip' => JText::_('OSM_STRIPE_ERROR_INCORRECT_ZIP'),
'card_declined' => JText::_('OSM_STRIPE_ERROR_CARD_DECLINED'),
'processing_error' => JText::_('OSM_STRIPE_ERROR_PROCESS_ERROR'),
];
$document->addScriptDeclaration('var osmStripeErrors = ' . json_encode($this->stripeErrors) . ";\n");
parent::__construct($params, $config);
}
/**
* Process Payment
*
* @param OSMembershipTableSubscriber $row
* @param array $data
*
* @return void
*
* @throws Exception
*/
public function processPayment($row, $data)
{
$app = JFactory::getApplication();
$Itemid = $app->input->getInt('Itemid', 0);
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
if (!empty($data['stripeToken']))
{
$card = $data['stripeToken'];
}
else
{
$card = array(
'number' => $data['x_card_num'],
'exp_month' => $data['exp_month'],
'exp_year' => $data['exp_year'],
'cvc' => $data['x_card_code'],
'name' => $data['card_holder_name']
);
}
$request = array(
'amount' => 100 * round($data['amount'], 2),
'currency' => $data['currency'],
'description' => $data['item_name'],
'card' => $card
);
$session = JFactory::getSession();
try
{
$charge = \Stripe\Charge::create($request);
$this->onPaymentSuccess($row, $charge->id);
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=complete&Itemid=' . $Itemid, false, false));
}
catch (\Stripe\Error\Card $e)
{
$stripeCode = $e->getStripeCode();
if (!empty($this->stripeErrors[$stripeCode]))
{
$errorMessage = $this->stripeErrors[$stripeCode];
}
else
{
$errorMessage = $e->getMessage();
}
$session->set('omnipay_payment_error_reason', $errorMessage);
}
catch (Exception $e)
{
$session->set('omnipay_payment_error_reason', $e->getMessage());
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=failure&id=' . $row->id . '&Itemid=' . $Itemid, false, false));
}
}
/**
* Process recurring subscription
*
* @param OSMembershipTableSubscriber $row
* @param array $data
*
* @return bool
* @throws Exception
*/
public function processRecurringPayment($row, $data)
{
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
$app = JFactory::getApplication();
$Itemid = $app->input->getInt('Itemid', 0);
$rowPlan = OSMembershipHelperDatabase::getPlan((int) $row->plan_id);
// Create the stripe plan if it doesn't exist
$stripePlanId = 'membership_plan_' . $rowPlan->id . '_' . (100 * $data['regular_price']);
$frequency = $rowPlan->subscription_length_unit;
$length = $rowPlan->subscription_length;
switch ($frequency)
{
case 'D':
$unit = 'day';
break;
case 'W':
$unit = 'week';
break;
case 'M':
$unit = 'month';
break;
case 'Y':
$unit = 'year';
break;
}
// Create a new stripe plan
$request = array(
"product" => array(
'name' => $rowPlan->title,
),
'id' => $stripePlanId,
'amount' => 100 * $data['regular_price'],
'currency' => $data['currency'],
'interval' => $unit,
'interval_count' => $length
);
$membershipProVersion = OSMembershipHelper::getInstalledVersion();
if (version_compare($membershipProVersion, '2.5.0', 'ge'))
{
$trialDuration = $data['trial_duration'];
$trialDurationUnit = $data['trial_duration_unit'];
}
else
{
$trialDuration = $rowPlan->trial_duration;
$trialDurationUnit = $rowPlan->trial_duration_unit;
}
if ($trialDuration > 0)
{
// Calculate the amount
switch ($trialDurationUnit)
{
case 'D':
$trialDays = $trialDuration;
break;
case 'W':
$trialDays = 7 * $trialDuration;
break;
case 'M':
$trialDays = 30 * $trialDuration;
break;
case 'Y':
$trialDays = 365 * $trialDuration;
break;
}
}
try
{
\Stripe\Plan::create($request);
}
catch (Exception $e)
{
// Assure that the plan exists already
}
if (!empty($data['stripeToken']))
{
$card = $data['stripeToken'];
}
else
{
$card = array(
'number' => $data['x_card_num'],
'exp_month' => $data['exp_month'],
'exp_year' => $data['exp_year'],
'cvc' => $data['x_card_code'],
'name' => $data['card_holder_name']
);
}
// Creating customer
try
{
$customer = \Stripe\Customer::create(array(
"description" => rtrim($row->first_name . ' ' . $row->last_name),
"source" => $card,
'email' => $row->email,
));
}
catch (Exception $e)
{
$session = JFactory::getSession();
$session->set('omnipay_payment_error_reason', 'Creating customer error :' . $e->getMessage());
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=failure&id=' . $row->id . '&Itemid=' . $Itemid, false, false));
return false;
}
$transactionId = '';
// Make a charge in case there is trial amount
if ($trialDuration > 0 && $data['trial_amount'] > 0)
{
$request = array(
'amount' => 100 * round($data['trial_amount'], 2),
'currency' => $data['currency'],
'description' => JText::sprintf('OSM_PAYMENT_FOR_TRIAL_SUBSCRIPTION', $rowPlan->title),
'receipt_email' => $row->email,
'customer' => $customer->id,
);
try
{
$charge = \Stripe\Charge::create($request);
$transactionId = $charge->id;
}
catch (Exception $e)
{
$session = JFactory::getSession();
$session->set('omnipay_payment_error_reason', 'Creating charge error:' . $e->getMessage());
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=failure&id=' . $row->id . '&Itemid=' . $Itemid, false, false));
return false;
}
}
// Next, create subscription
$request = array(
'customer' => $customer->id,
'items' => array(
array(
'plan' => $stripePlanId,
)
)
);
if (!empty($trialDays))
{
$request['trial_period_days'] = $trialDays;
}
try
{
$subscription = \Stripe\Subscription::create($request);
if (property_exists($row, 'subscription_id'))
{
$row->subscription_id = $subscription->id;
}
if (property_exists($row, 'gateway_customer_id'))
{
$row->gateway_customer_id = $customer->id;
}
if ($trialDuration > 0)
{
if (!$row->is_free_trial)
{
$row->payment_made = 1;
}
$this->onPaymentSuccess($row, $transactionId);
}
else
{
// Just store the subscription id and leave the payment event to send email
$row->published = 1;
$row->store();
}
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=complete&Itemid=' . $Itemid, false, false));
}
catch (Exception $e)
{
$session = JFactory::getSession();
$session->set('omnipay_payment_error_reason', 'Creating subscription error ' . $e->getMessage());
$app->redirect(JRoute::_('index.php?option=com_osmembership&view=failure&id=' . $row->id . '&Itemid=' . $Itemid, false, false));
}
}
/**
*
* @param $row
*
* @return bool
* @throws Exception
*/
public function cancelSubscription($row)
{
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
try
{
\Stripe\Subscription::retrieve($row->subscription_id)->cancel();
return true;
}
catch (Exception $e)
{
JFactory::getApplication()->enqueueMessage($e->getMessage(), 'error');
return false;
}
}
public function verifyRecurringPayment()
{
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
$body = @file_get_contents('php://input');
$event_json = json_decode($body);
$event_id = $event_json->id;
try
{
$event = \Stripe\Event::retrieve($event_id);
}
catch (Exception $e)
{
$event = null;
}
if ($event && $event->type == 'invoice.payment_succeeded' && !empty($event->data->object->subscription))
{
$transactionId = $event->data->object->charge;
$subscriptionId = $event->data->object->subscription;
if ($transactionId && OSMembershipHelper::isTransactionProcessed($transactionId))
{
return;
}
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('id')
->from('#__osmembership_subscribers')
->where('subscription_id = ' . $db->quote($subscriptionId))
->order('id');
$db->setQuery($query, 0, 1);
$id = (int) $db->loadResult();
$this->logGatewayData('invoice.payment_succeeded' . (string) $query . ' ' . $subscriptionId . ' ' . $transactionId);
if ($id > 0)
{
/* @var OSMembershipTableSubscriber $row */
$row = JTable::getInstance('OsMembership', 'Subscriber');
$row->load($id);
// First payment, store Transaction ID and email customers
if ($row->payment_made == 0)
{
$row->payment_made = 1;
$this->onPaymentSuccess($row, $transactionId);
}
else
{
$version = OSmembershipHelper::getInstalledVersion();
if (version_compare($version, '2.14.0', 'ge'))
{
/* @var OSMembershipModelApi $model */
$model = MPFModel::getInstance('Api', 'OSMembershipModel', ['ignore_request' => true]);
$model->renewRecurringSubscription($id, $subscriptionId, $transactionId);
}
else
{
OSMembershipHelper::extendRecurringSubscription($id, $transactionId, $subscriptionId);
}
}
}
}
}
/**
* Method to update customer credit card
*
* @param array $data
* @param OSMembershipTableSubscriber $subscription
*
* @throws Exception
*/
public function updateCard($data, $subscription)
{
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
try
{
if (!empty($subscription->gateway_customer_id))
{
$cu = \Stripe\Customer::retrieve($subscription->gateway_customer_id); // stored in your application
}
else
{
$sub = \Stripe\Subscription::retrieve($subscription->subscription_id);
$cu = \Stripe\Customer::retrieve($sub->customer);
}
if (!empty($data['stripeToken']))
{
$cu->source = $data['stripeToken']; // obtained with Checkout
}
else
{
$cu->source = array(
'number' => $data['x_card_num'],
'exp_month' => $data['exp_month'],
'exp_year' => $data['exp_year'],
'cvc' => $data['x_card_code'],
'name' => $data['card_holder_name']
);
}
$cu->save();
}
catch (\Stripe\Error\Card $e)
{
// Use the variable $error to save any errors
// To be displayed to the customer later in the page
$body = $e->getJsonBody();
$err = $body['error'];
$error = $err['message'];
throw new Exception($error);
}
}
/**
* Refund a transaction
*
* @param OSMembershipTableSubscriber $row
*
* @throws Exception
*/
public function refund($row)
{
\Stripe\Stripe::setApiKey($this->params->get('stripe_api_key'));
try
{
\Stripe\Refund::create(['charge' => $row->transaction_id]);
}
catch (\Stripe\Error\Card $e)
{
// Use the variable $error to save any errors
// To be displayed to the customer later in the page
$body = $e->getJsonBody();
$err = $body['error'];
$error = $err['message'];
throw new Exception($error);
}
}
}