public function processControllerRequest(PhortuneProviderController $controller, AphrontRequest $request)
 {
     $cart = $controller->loadCart($request->getInt('cartID'));
     if (!$cart) {
         return new Aphront404Response();
     }
     switch ($controller->getAction()) {
         case 'checkout':
             $return_uri = $this->getControllerURI('charge', array('cartID' => $cart->getID()));
             $cancel_uri = $this->getControllerURI('cancel', array('cartID' => $cart->getID()));
             $total_in_cents = $cart->getTotalPriceInCents();
             $price = PhortuneCurrency::newFromUSDCents($total_in_cents);
             $result = $this->newPaypalAPICall()->setRawPayPalQuery('SetExpressCheckout', array('PAYMENTREQUEST_0_AMT' => $price->formatBareValue(), 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(), 'RETURNURL' => $return_uri, 'CANCELURL' => $cancel_uri, 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale'))->resolve();
             $uri = new PhutilURI('https://www.sandbox.paypal.com/cgi-bin/webscr');
             $uri->setQueryParams(array('cmd' => '_express-checkout', 'token' => $result['TOKEN']));
             return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($uri);
         case 'charge':
             var_dump($_REQUEST);
             break;
         case 'cancel':
             var_dump($_REQUEST);
             break;
     }
     throw new Exception("The rest of this isn't implemented yet.");
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $product = id(new PhortuneProductQuery())->setViewer($user)->withIDs(array($this->productID))->executeOne();
     if (!$product) {
         return new Aphront404Response();
     }
     $title = pht('Product: %s', $product->getProductName());
     $header = id(new PHUIHeaderView())->setHeader($product->getProductName());
     $account = $this->loadActiveAccount($user);
     $edit_uri = $this->getApplicationURI('product/edit/' . $product->getID() . '/');
     $cart_uri = $this->getApplicationURI($account->getID() . '/buy/' . $product->getID() . '/');
     $actions = id(new PhabricatorActionListView())->setUser($user)->setObjectURI($request->getRequestURI())->addAction(id(new PhabricatorActionView())->setName(pht('Edit Product'))->setHref($edit_uri)->setIcon('fa-pencil'))->addAction(id(new PhabricatorActionView())->setUser($user)->setName(pht('Purchase'))->setHref($cart_uri)->setIcon('fa-shopping-cart')->setWorkflow(true));
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->setActionList($actions);
     $crumbs->addTextCrumb(pht('Products'), $this->getApplicationURI('product/'));
     $crumbs->addTextCrumb(pht('#%d', $product->getID()), $request->getRequestURI());
     $properties = id(new PHUIPropertyListView())->setUser($user)->setActionList($actions)->addProperty(pht('Type'), $product->getTypeName())->addProperty(pht('Price'), PhortuneCurrency::newFromUSDCents($product->getPriceInCents())->formatForDisplay());
     $xactions = id(new PhortuneProductTransactionQuery())->setViewer($user)->withObjectPHIDs(array($product->getPHID()))->execute();
     $engine = id(new PhabricatorMarkupEngine())->setViewer($user);
     $xaction_view = id(new PhabricatorApplicationTransactionView())->setUser($user)->setObjectPHID($product->getPHID())->setTransactions($xactions)->setMarkupEngine($engine);
     $object_box = id(new PHUIObjectBoxView())->setHeader($header)->addPropertyList($properties);
     return $this->buildApplicationPage(array($crumbs, $object_box, $xaction_view), array('title' => $title));
 }
 public function testCurrencyFormatBareValue()
 {
     // NOTE: The PayPal API depends on the behavior of the bare value format!
     $map = array(0 => '0.00', 1 => '0.01', 100 => '1.00', -123 => '-1.23', 5000000 => '50000.00');
     foreach ($map as $input => $expect) {
         $this->assertEqual($expect, PhortuneCurrency::newFromUSDCents($input)->formatBareValue(), "formatBareValue({$input})");
     }
 }
Beispiel #4
0
 public function getTotalPriceInCents()
 {
     $prices = array();
     foreach ($this->getPurchases() as $purchase) {
         $prices[] = PhortuneCurrency::newFromUSDCents($purchase->getTotalPriceInCents());
     }
     return PhortuneCurrency::newFromList($prices)->getValue();
 }
 public static function newFromList(array $list)
 {
     assert_instances_of($list, 'PhortuneCurrency');
     $total = 0;
     foreach ($list as $item) {
         // TODO: This should check for integer overflows, etc.
         $total += $item->getValue();
     }
     return PhortuneCurrency::newFromUSDCents($total);
 }
 protected function buildCartContents(PhortuneCart $cart)
 {
     $rows = array();
     $total = 0;
     foreach ($cart->getPurchases() as $purchase) {
         $rows[] = array($purchase->getFullDisplayName(), PhortuneCurrency::newFromUSDCents($purchase->getBasePriceInCents())->formatForDisplay(), $purchase->getQuantity(), PhortuneCurrency::newFromUSDCents($purchase->getTotalPriceInCents())->formatForDisplay());
         $total += $purchase->getTotalPriceInCents();
     }
     $rows[] = array(phutil_tag('strong', array(), pht('Total')), '', '', phutil_tag('strong', array(), PhortuneCurrency::newFromUSDCents($total)->formatForDisplay()));
     $table = new AphrontTableView($rows);
     $table->setHeaders(array(pht('Item'), pht('Price'), pht('Qty.'), pht('Total')));
     $table->setColumnClasses(array('wide', 'right', 'right', 'right'));
     return id(new PHUIObjectBoxView())->setHeaderText(pht('Cart Contents'))->appendChild($table);
 }
 protected function buildChargesTable(array $charges, $show_cart = true)
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $rows = array();
     foreach ($charges as $charge) {
         $cart = $charge->getCart();
         $cart_id = $cart->getID();
         $cart_uri = $this->getApplicationURI("cart/{$cart_id}/");
         $cart_href = phutil_tag('a', array('href' => $cart_uri), pht('Cart %d', $cart_id));
         $rows[] = array($charge->getID(), $cart_href, $charge->getPaymentProviderKey(), $charge->getPaymentMethodPHID(), PhortuneCurrency::newFromUSDCents($charge->getAmountInCents())->formatForDisplay(), $charge->getStatus(), phabricator_datetime($charge->getDateCreated(), $viewer));
     }
     $charge_table = id(new AphrontTableView($rows))->setHeaders(array(pht('ID'), pht('Cart'), pht('Provider'), pht('Method'), pht('Amount'), pht('Status'), pht('Created')))->setColumnClasses(array('', 'strong', '', '', 'wide right', '', ''))->setColumnVisibility(array(true, $show_cart));
     $header = id(new PHUIHeaderView())->setHeader(pht('Charge History'));
     return id(new PHUIObjectBoxView())->setHeader($header)->appendChild($charge_table);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     $pager = new AphrontCursorPagerView();
     $pager->readFromRequest($request);
     $query = id(new PhortuneProductQuery())->setViewer($user);
     $products = $query->executeWithCursorPager($pager);
     $title = pht('Product List');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb('Products', $this->getApplicationURI('product/'));
     $crumbs->addAction(id(new PHUIListItemView())->setName(pht('Create Product'))->setHref($this->getApplicationURI('product/edit/'))->setIcon('fa-plus-square'));
     $product_list = id(new PHUIObjectItemListView())->setUser($user)->setNoDataString(pht('No products.'));
     foreach ($products as $product) {
         $view_uri = $this->getApplicationURI('product/view/' . $product->getID() . '/');
         $price = $product->getPriceInCents();
         $item = id(new PHUIObjectItemView())->setObjectName($product->getID())->setHeader($product->getProductName())->setHref($view_uri)->addAttribute(PhortuneCurrency::newFromUSDCents($price)->formatForDisplay())->addAttribute($product->getTypeName());
         $product_list->addItem($item);
     }
     return $this->buildApplicationPage(array($crumbs, $product_list, $pager), array('title' => $title));
 }
 private function buildPurchaseHistorySection(PhortuneAccount $account)
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $carts = id(new PhortuneCartQuery())->setViewer($viewer)->withAccountPHIDs(array($account->getPHID()))->needPurchases(true)->withStatuses(array(PhortuneCart::STATUS_PURCHASING, PhortuneCart::STATUS_PURCHASED))->execute();
     $rows = array();
     $rowc = array();
     foreach ($carts as $cart) {
         $cart_link = phutil_tag('a', array('href' => $this->getApplicationURI('cart/' . $cart->getID() . '/')), pht('Cart %d', $cart->getID()));
         $rowc[] = 'highlighted';
         $rows[] = array(phutil_tag('strong', array(), $cart_link), '', '');
         foreach ($cart->getPurchases() as $purchase) {
             $id = $purchase->getID();
             $price = $purchase->getTotalPriceInCents();
             $price = PhortuneCurrency::newFromUSDCents($price)->formatForDisplay();
             $purchase_link = phutil_tag('a', array('href' => $this->getApplicationURI('purchase/' . $id . '/')), $purchase->getFullDisplayName());
             $rowc[] = '';
             $rows[] = array('', $purchase_link, $price);
         }
     }
     $table = id(new AphrontTableView($rows))->setRowClasses($rowc)->setHeaders(array(pht('Cart'), pht('Purchase'), pht('Amount')))->setColumnClasses(array('', 'wide', 'right'));
     $header = id(new PHUIHeaderView())->setHeader(pht('Purchase History'));
     return id(new PHUIObjectBoxView())->setHeader($header)->appendChild($table);
 }
 protected function renderResultList(array $backers, PhabricatorSavedQuery $query, array $handles)
 {
     assert_instances_of($backers, 'FundBacker');
     $viewer = $this->requireViewer();
     $list = id(new PHUIObjectItemListView());
     foreach ($backers as $backer) {
         $backer_handle = $handles[$backer->getBackerPHID()];
         $currency = PhortuneCurrency::newFromUSDCents($backer->getAmountInCents());
         $header = pht('%s for %s', $currency->formatForDisplay(), $handles[$backer->getInitiativePHID()]->renderLink());
         $item = id(new PHUIObjectItemView())->setHeader($header)->addIcon('none', phabricator_datetime($backer->getDateCreated(), $viewer))->addByline(pht('Backer: %s', $backer_handle->renderLink()));
         $list->addItem($item);
     }
     return $list;
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     if ($this->productID) {
         $product = id(new PhortuneProductQuery())->setViewer($user)->withIDs(array($this->productID))->executeOne();
         if (!$product) {
             return new Aphront404Response();
         }
         $is_create = false;
         $cancel_uri = $this->getApplicationURI('product/view/' . $this->productID . '/');
     } else {
         $product = new PhortuneProduct();
         $is_create = true;
         $cancel_uri = $this->getApplicationURI('product/');
     }
     $v_name = $product->getProductName();
     $v_type = $product->getProductType();
     $v_price = (int) $product->getPriceInCents();
     $display_price = PhortuneCurrency::newFromUSDCents($v_price)->formatForDisplay();
     $e_name = true;
     $e_type = null;
     $e_price = true;
     $errors = array();
     if ($request->isFormPost()) {
         $v_name = $request->getStr('name');
         if (!strlen($v_name)) {
             $e_name = pht('Required');
             $errors[] = pht('Product must have a name.');
         } else {
             $e_name = null;
         }
         if ($is_create) {
             $v_type = $request->getStr('type');
             $type_map = PhortuneProduct::getTypeMap();
             if (empty($type_map[$v_type])) {
                 $e_type = pht('Invalid');
                 $errors[] = pht('Product type is invalid.');
             } else {
                 $e_type = null;
             }
         }
         $display_price = $request->getStr('price');
         try {
             $v_price = PhortuneCurrency::newFromUserInput($user, $display_price)->getValue();
             $e_price = null;
         } catch (Exception $ex) {
             $errors[] = pht('Price should be formatted as: $1.23');
             $e_price = pht('Invalid');
         }
         if (!$errors) {
             $xactions = array();
             $xactions[] = id(new PhortuneProductTransaction())->setTransactionType(PhortuneProductTransaction::TYPE_NAME)->setNewValue($v_name);
             $xactions[] = id(new PhortuneProductTransaction())->setTransactionType(PhortuneProductTransaction::TYPE_TYPE)->setNewValue($v_type);
             $xactions[] = id(new PhortuneProductTransaction())->setTransactionType(PhortuneProductTransaction::TYPE_PRICE)->setNewValue($v_price);
             $editor = id(new PhortuneProductEditor())->setActor($user)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request);
             $editor->applyTransactions($product, $xactions);
             return id(new AphrontRedirectResponse())->setURI($this->getApplicationURI('product/view/' . $product->getID() . '/'));
         }
     }
     if ($errors) {
         $errors = id(new AphrontErrorView())->setErrors($errors);
     }
     $form = id(new AphrontFormView())->setUser($user)->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Name'))->setName('name')->setValue($v_name)->setError($e_name))->appendChild(id(new AphrontFormSelectControl())->setLabel(pht('Type'))->setName('type')->setValue($v_type)->setError($e_type)->setOptions(PhortuneProduct::getTypeMap())->setDisabled(!$is_create))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Price'))->setName('price')->setValue($display_price)->setError($e_price))->appendChild(id(new AphrontFormSubmitControl())->setValue($is_create ? pht('Create Product') : pht('Save Product'))->addCancelButton($cancel_uri));
     $title = pht('Edit Product');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Products'), $this->getApplicationURI('product/'));
     $crumbs->addTextCrumb($is_create ? pht('Create') : pht('Edit'), $request->getRequestURI());
     $box = id(new PHUIObjectBoxView())->setHeaderText(pht('Edit Product'))->appendChild($form);
     return $this->buildApplicationPage(array($crumbs, $box), array('title' => $title));
 }
 /**
  * @phutil-external-symbol class WePay
  */
 public function processControllerRequest(PhortuneProviderController $controller, AphrontRequest $request)
 {
     $viewer = $request->getUser();
     $cart = $controller->loadCart($request->getInt('cartID'));
     if (!$cart) {
         return new Aphront404Response();
     }
     $cart_uri = '/phortune/cart/' . $cart->getID() . '/';
     $root = dirname(phutil_get_library_root('phabricator'));
     require_once $root . '/externals/wepay/wepay.php';
     WePay::useStaging($this->getWePayClientID(), $this->getWePayClientSecret());
     $wepay = new WePay($this->getWePayAccessToken());
     switch ($controller->getAction()) {
         case 'checkout':
             $return_uri = $this->getControllerURI('charge', array('cartID' => $cart->getID()));
             $cancel_uri = $this->getControllerURI('cancel', array('cartID' => $cart->getID()));
             $total_in_cents = $cart->getTotalPriceInCents();
             $price = PhortuneCurrency::newFromUSDCents($total_in_cents);
             $params = array('account_id' => $this->getWePayAccountID(), 'short_description' => 'Services', 'type' => 'SERVICE', 'amount' => $price->formatBareValue(), 'long_description' => 'Services', 'reference_id' => $cart->getPHID(), 'app_fee' => 0, 'fee_payer' => 'Payee', 'redirect_uri' => $return_uri, 'fallback_uri' => $cancel_uri, 'auto_capture' => true, 'require_shipping' => 0, 'shipping_fee' => 0, 'charge_tax' => 0, 'mode' => 'regular', 'funding_sources' => 'bank,cc');
             $result = $wepay->request('checkout/create', $params);
             // TODO: We must store "$result->checkout_id" on the Cart since the
             // user might not end up back here. Really this needs a bunch of junk.
             $uri = new PhutilURI($result->checkout_uri);
             return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($uri);
         case 'charge':
             $checkout_id = $request->getInt('checkout_id');
             $params = array('checkout_id' => $checkout_id);
             $checkout = $wepay->request('checkout', $params);
             if ($checkout->reference_id != $cart->getPHID()) {
                 throw new Exception(pht('Checkout reference ID does not match cart PHID!'));
             }
             switch ($checkout->state) {
                 case 'authorized':
                 case 'reserved':
                 case 'captured':
                     break;
                 default:
                     throw new Exception(pht('Checkout is in bad state "%s"!', $result->state));
             }
             $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
             $charge = id(new PhortuneCharge())->setAmountInCents((int) $checkout->gross * 100)->setAccountPHID($cart->getAccount()->getPHID())->setAuthorPHID($viewer->getPHID())->setPaymentProviderKey($this->getProviderKey())->setCartPHID($cart->getPHID())->setStatus(PhortuneCharge::STATUS_CHARGING)->save();
             $cart->openTransaction();
             $charge->setStatus(PhortuneCharge::STATUS_CHARGED);
             $charge->save();
             $cart->setStatus(PhortuneCart::STATUS_PURCHASED);
             $cart->save();
             $cart->saveTransaction();
             unset($unguarded);
             return id(new AphrontRedirectResponse())->setIsExternal(true)->setURI($cart_uri);
         case 'cancel':
             var_dump($_REQUEST);
             break;
     }
     throw new Exception("The rest of this isn't implemented yet.");
 }