Skip to content

Instantly share code, notes, and snippets.

@rei999
Created March 26, 2015 01:25
Show Gist options
  • Save rei999/dbcbdaed69c5b09476a1 to your computer and use it in GitHub Desktop.
Save rei999/dbcbdaed69c5b09476a1 to your computer and use it in GitHub Desktop.
Kenneth Sample Code - Upgrade to premium membership with Stripe
<?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