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})"); } }
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."); }