Created
March 26, 2015 01:25
-
-
Save rei999/dbcbdaed69c5b09476a1 to your computer and use it in GitHub Desktop.
Kenneth Sample Code - Upgrade to premium membership with Stripe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace MoonLight\MainBundle\Controller; | |
use Symfony\Bundle\FrameworkBundle\Controller\Controller; | |
use FOS\RestBundle\View\View; | |
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; | |
use Aml\UserBundle\Entity\User; | |
use MoonLight\MainBundle\Entity\Transaction; | |
use MoonLight\MainBundle\Entity\FailedTransaction; | |
use MoonLight\MainBundle\Entity\Membership; | |
use MoonLight\MainBundle\Repository\TransactionRepository; | |
use MoonLight\MainBundle\Repository\MembershipRepository; | |
use MoonLight\MainBundle\Repository\FailedTransactionRepository; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpFoundation\Response; | |
use MoonLight\MainBundle\Util\TextUtil; | |
use Symfony\Component\Security\Core\Exception\AccessDeniedException; | |
class TransactionController extends Controller | |
{ | |
const RESP_SUCCESS = 0; | |
const RESP_NO_PARAM = 1; | |
const RESP_NO_QUIZ = 2; | |
const RESP_CHARGE_ERR = 3; | |
const RESP_NOT_POST = 4; | |
const MEMBERSHIP_PRICE = 60; | |
const RESP_INVALID = 2; | |
/** | |
* @Template() | |
*/ | |
public function listPurchasesAction($page = 0) | |
{ | |
$user = $this->get('security.context')->getToken()->getUser(); | |
$em = $this->getDoctrine()->getManager(); | |
$txns = $em->getRepository('MoonLightMainBundle:Transaction')->findByBuyerId($user->getId(), $page); | |
$route = 'list_purchases'; | |
return array('txns' => $txns, 'page' => ++$page, 'max_num' => TransactionRepository::RECORD_PER_PAGE, 'route' => $route); | |
} | |
/** | |
* Upgrade membership to premium | |
*/ | |
public function processUpgradeAction(Request $request) { | |
if ($request->getMethod() == 'POST') { | |
$itemId = $request->request->get('itemId'); | |
$stripeToken = $request->request->get('stripeToken'); | |
if($itemId == null || $itemId == "" || $stripeToken == null || $stripeToken == "") { | |
$msg = $this->container->get('translator')->trans('transaction.empty_parameters', array(), 'AmlUserBundle'); | |
$dataOut = array("responseCode" => TransactionController::RESP_NO_PARAM, "message" => $msg); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} | |
$em = $this->getDoctrine()->getManager(); | |
$membership = $em->getRepository('MoonLightMainBundle:Membership')->find(Membership::ID_PREMIUM); | |
if($membership == null) { | |
$msg = $this->container->get('translator')->trans('transaction.membership_not_exist', array(), 'AmlUserBundle'); | |
$dataOut = array("responseCode" => TransactionController::RESP_INVALID, "message" => $msg); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} | |
$buyer = $this->get('security.context')->getToken()->getUser(); | |
$em = $this->getDoctrine()->getManager(); | |
$transaction = $em->getRepository('MoonLightMainBundle:Transaction')->findItem(Transaction::TYPE_PREMIUM_MEMBERSHIP, null, $buyer->getId()); | |
if($transaction == null) { | |
$stripeSecret = $this->container->getParameter('stripe_secret'); | |
\Stripe::setApiKey($stripeSecret); | |
$txnId = $buyer->getId() . uniqid(); | |
$logMsg = null; | |
// Create the charge on Stripe's servers - this will charge the user's card | |
try { | |
$charge = \Stripe_Charge::create(array( | |
"amount" => $membership->getPrice() * 100, // amount in cents | |
"currency" => "usd", | |
"card" => $stripeToken['id'], | |
"description" => $stripeToken['email'], | |
"metadata" => array( | |
"email" => $buyer->getEmail(), | |
"item_id" => $itemId, | |
"item_title" => $membership->getName() | |
) | |
)); | |
// log successful transaction | |
$logMsg = $charge->id; | |
$successTxn = new Transaction(); | |
$successTxn->setBuyer($buyer); | |
$successTxn->setType(Transaction::TYPE_PREMIUM_MEMBERSHIP); | |
$successTxn->setItemId($itemId); | |
$successTxn->setItemTitle($membership->getName()); | |
$successTxn->setStripeResp($logMsg); | |
$successTxn->setTxnId($txnId); | |
$successTxn->setPrice($membership->getPrice()); | |
$successTxn->setCommission($membership->getPrice()); | |
$em->persist($successTxn); | |
// set user to premium membership | |
$buyer->setAccountType(User::ACCOUNT_PREMIUM); | |
$expirationDate = new \DateTime("now"); | |
$expirationDate->modify('+365 days'); | |
$buyer->setExpirationDate($expirationDate); | |
$buyer->setRoles(array(User::ROLE_PREMIUM)); | |
$em->persist($buyer); | |
$em->flush(); | |
// inform user about his/her purchases by email | |
$mailSubject = $this->container->get('translator')->trans('transaction.membership.email_checkout_success.subject', array( | |
'%itemDes%' => $membership->getName() | |
), 'AmlUserBundle'); | |
$mailBody = $this->container->get('translator')->trans('transaction.membership.email_checkout_success.body', array( | |
'%name%' => $buyer->getUsername(), | |
'%txnId%' => $txnId, | |
'%itemDes%' => $membership->getName(), | |
'%itemUrl%' => $this->container->getParameter('domain') . $this->generateUrl('membership_instruction', array()), | |
'%receiptUrl%' => $this->container->getParameter('domain') . $this->generateUrl('list_purchases', array())), 'AmlUserBundle'); | |
$message = \Swift_Message::newInstance() | |
->setSubject($mailSubject) | |
->setFrom($this->container->getParameter('email')) | |
->setTo($buyer->getEmail()) | |
->setBody($mailBody); | |
$this->container->get('mailer')->send($message); | |
$dataOut = array("responseCode" => TransactionController::RESP_SUCCESS, "message" => "success"); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} catch(\Stripe_CardError $e) { | |
$stripBody = $chargeError->getJsonBody(); | |
$err = $stripBody['error']; | |
$logMsg = 'Status is:' . $chargeError->getHttpStatus() . ". "; | |
$logMsg .= 'Type is:' . $err['type'] . ". "; | |
$logMsg .= 'Code is:' . $err['code'] . ". "; | |
$logMsg .= 'Param is:' . $err['param'] . ". "; | |
$logMsg .= 'Message is:' . $err['message'] . "."; | |
} catch (\Stripe_InvalidRequestError $e) { | |
// Invalid parameters were supplied to Stripe's API | |
$logMsg = "Stripe_InvalidRequestError: " . $e->getMessage(); | |
} catch (\Stripe_AuthenticationError $e) { | |
// Authentication with Stripe's API failed | |
// (maybe you changed API keys recently) | |
$logMsg = "Stripe_AuthenticationError: " . $e->getMessage(); | |
} catch (\Stripe_ApiConnectionError $e) { | |
// Network communication with Stripe failed | |
$logMsg = "Stripe_ApiConnectionError: " . $e->getMessage(); | |
} catch (\Stripe_Error $e) { | |
// Display a very generic error to the user | |
$logMsg = "Stripe_Error: " . $e->getMessage(); | |
} catch (\Exception $e) { | |
// Something else happened, completely unrelated to Stripe | |
$logMsg = "Generic Exception: " . $e->getMessage(); | |
} | |
// Transaction failed. Log the error and email admin | |
if($logMsg != null) { | |
$failedTxn = new FailedTransaction(); | |
$failedTxn->setBuyer($buyer); | |
$failedTxn->setType(Transaction::TYPE_PREMIUM_MEMBERSHIP); | |
$failedTxn->setItemId($itemId); | |
$failedTxn->setItemTitle($membership->getName()); | |
$failedTxn->setStripeResp($logMsg); | |
$failedTxn->setTxnId($txnId); | |
$failedTxn->setPrice($membership->getPrice()); | |
$em->persist($failedTxn); | |
$em->flush(); | |
$mailSubject = $this->container->get('translator')->trans('transaction.email_checkout_failed.subject', array(), 'AmlUserBundle'); | |
$mailBody = $this->container->get('translator')->trans('transaction.email_checkout_failed.body', array( | |
'%name%' => $buyer->getUsername(), | |
'%id%' => $buyer->getId(), | |
'%seller%' => $this->container->getParameter('app_name'), | |
'%sellerId%' => "none", | |
'%email%' => $buyer->getEmail(), | |
'%txnId%' => $txnId, | |
'%itemId%'=> $itemId, | |
'%itemDes%' => $membership->getName(), | |
'%message%' => $logMsg | |
), 'AmlUserBundle'); | |
$message = \Swift_Message::newInstance() | |
->setSubject($mailSubject) | |
->setFrom($this->container->getParameter('email')) | |
->setTo($this->container->getParameter('email')) | |
->setBody($mailBody); | |
$this->container->get('mailer')->send($message); | |
$dataOut = array("responseCode" => TransactionController::RESP_CHARGE_ERR, "message" => $logMsg); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} | |
// user has bought the upgrade previously | |
} else { | |
$this->get('session')->getFlashBag()->add('notice', $this->container->get('translator')->trans('transaction.bought_already', array(), 'AmlUserBundle')); | |
$dataOut = array("responseCode" => 0, "message" => $message); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} | |
// not a POST method | |
} else { | |
$msg = $this->container->get('translator')->trans('transaction.invalid_response', array(), 'AmlUserBundle'); | |
$dataOut = array("responseCode" => TransactionController::RESP_NOT_POST, "message" => $msg); | |
$return = json_encode($dataOut); | |
return new Response($return, 200); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment