From d6eb1c67e769986870bbe760ac5f14921e95c67b Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 23 Jul 2014 10:36:25 -0700 Subject: [PATCH] Phortune Cart Status, some one-time support Summary: Ref T2787. Carts need a status so we can tell if they've been purchased. Also kind of get WePay working as a one-time provider, and let charges not have a methodPHID (they won't for one-time providers). All the status stuff is still super crazy rough and you can do things like start a checkout, add a bunch of stuff to your cart, complete the checkout, and have Phabricator think you paid for all the stuff you added. But this is fine for now since you can't actually edit carts, and also none of this is at all usable anyway. I'll refine some of the workflows in future diffs, for now I'm just getting things hooked up and technically working. Test Plan: - Purcahsed a cart and got a sort of status/done screen instead of a "your money is gone" exception. - Went through the WePay flow and got a successful test checkout. Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10003 --- .../20140721.phortune.4.cartstatus.sql | 2 + .../20140721.phortune.5.cstatusdefault.sql | 2 + .../20140721.phortune.6.onetimecharge.sql | 3 + .../20140721.phortune.7.nullmethod.sql | 4 ++ src/__phutil_library_map__.php | 8 ++- .../PhabricatorPhortuneApplication.php | 5 +- .../PhortuneAccountViewController.php | 40 +---------- ...php => PhortuneCartCheckoutController.php} | 57 +++------------- .../controller/PhortuneCartController.php | 52 +++++++++++++++ .../controller/PhortuneCartViewController.php | 50 ++++++++++++++ .../controller/PhortuneController.php | 47 +++++++++++++ .../PhortuneProductPurchaseController.php | 4 +- .../controller/PhortuneProviderController.php | 14 +++- .../PhortunePaypalPaymentProvider.php | 2 +- .../provider/PhortuneWePayPaymentProvider.php | 66 ++++++++++++++++--- .../phortune/query/PhortuneChargeQuery.php | 13 ++++ .../phortune/storage/PhortuneCart.php | 9 +-- .../phortune/storage/PhortuneCharge.php | 1 + 18 files changed, 274 insertions(+), 105 deletions(-) create mode 100644 resources/sql/autopatches/20140721.phortune.4.cartstatus.sql create mode 100644 resources/sql/autopatches/20140721.phortune.5.cstatusdefault.sql create mode 100644 resources/sql/autopatches/20140721.phortune.6.onetimecharge.sql create mode 100644 resources/sql/autopatches/20140721.phortune.7.nullmethod.sql rename src/applications/phortune/controller/{PhortuneAccountBuyController.php => PhortuneCartCheckoutController.php} (76%) create mode 100644 src/applications/phortune/controller/PhortuneCartController.php create mode 100644 src/applications/phortune/controller/PhortuneCartViewController.php diff --git a/resources/sql/autopatches/20140721.phortune.4.cartstatus.sql b/resources/sql/autopatches/20140721.phortune.4.cartstatus.sql new file mode 100644 index 0000000000..fc18eb78dc --- /dev/null +++ b/resources/sql/autopatches/20140721.phortune.4.cartstatus.sql @@ -0,0 +1,2 @@ +ALTER TABLE {$NAMESPACE}_phortune.phortune_cart + ADD status VARCHAR(32) NOT NULL COLLATE utf8_bin; diff --git a/resources/sql/autopatches/20140721.phortune.5.cstatusdefault.sql b/resources/sql/autopatches/20140721.phortune.5.cstatusdefault.sql new file mode 100644 index 0000000000..1232164f46 --- /dev/null +++ b/resources/sql/autopatches/20140721.phortune.5.cstatusdefault.sql @@ -0,0 +1,2 @@ +UPDATE {$NAMESPACE}_phortune.phortune_cart + SET status = 'cart:ready' WHERE status = ''; diff --git a/resources/sql/autopatches/20140721.phortune.6.onetimecharge.sql b/resources/sql/autopatches/20140721.phortune.6.onetimecharge.sql new file mode 100644 index 0000000000..4152efb0d0 --- /dev/null +++ b/resources/sql/autopatches/20140721.phortune.6.onetimecharge.sql @@ -0,0 +1,3 @@ +ALTER TABLE {$NAMESPACE}_phortune.phortune_charge + ADD paymentProviderKey VARCHAR(128) NOT NULL COLLATE utf8_bin + AFTER cartPHID; diff --git a/resources/sql/autopatches/20140721.phortune.7.nullmethod.sql b/resources/sql/autopatches/20140721.phortune.7.nullmethod.sql new file mode 100644 index 0000000000..d843251bb0 --- /dev/null +++ b/resources/sql/autopatches/20140721.phortune.7.nullmethod.sql @@ -0,0 +1,4 @@ +/* Make this nullable to support one-time providers. */ + +ALTER TABLE {$NAMESPACE}_phortune.phortune_charge + CHANGE paymentMethodPHID paymentMethodPHID VARCHAR(64) COLLATE utf8_bin; diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 9883926b7a..2f753ed5c4 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2488,7 +2488,6 @@ phutil_register_library_map(array( 'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php', 'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php', 'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php', - 'PhortuneAccountBuyController' => 'applications/phortune/controller/PhortuneAccountBuyController.php', 'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php', 'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php', 'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php', @@ -2496,7 +2495,10 @@ phutil_register_library_map(array( 'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php', 'PhortuneBalancedPaymentProvider' => 'applications/phortune/provider/PhortuneBalancedPaymentProvider.php', 'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php', + 'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php', + 'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php', 'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php', + 'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php', 'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php', 'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php', 'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php', @@ -5371,7 +5373,6 @@ phutil_register_library_map(array( 'PhortuneDAO', 'PhabricatorPolicyInterface', ), - 'PhortuneAccountBuyController' => 'PhortuneController', 'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor', 'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction', @@ -5382,7 +5383,10 @@ phutil_register_library_map(array( 'PhortuneDAO', 'PhabricatorPolicyInterface', ), + 'PhortuneCartCheckoutController' => 'PhortuneCartController', + 'PhortuneCartController' => 'PhortuneController', 'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhortuneCartViewController' => 'PhortuneCartController', 'PhortuneCharge' => array( 'PhortuneDAO', 'PhabricatorPolicyInterface', diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php index 64df95fd4b..d2eb2338e0 100644 --- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php +++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php @@ -41,7 +41,10 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication { ), 'buy/(?P\d+)/' => 'PhortuneProductPurchaseController', ), - 'cart/(?P\d+)/' => 'PhortuneAccountBuyController', + 'cart/(?P\d+)/' => array( + '' => 'PhortuneCartViewController', + 'checkout/' => 'PhortuneCartCheckoutController', + ), 'account/' => array( '' => 'PhortuneAccountListController', 'edit/(?:(?P\d+)/)?' => 'PhortuneAccountEditController', diff --git a/src/applications/phortune/controller/PhortuneAccountViewController.php b/src/applications/phortune/controller/PhortuneAccountViewController.php index 1124399d10..1914a3ef41 100644 --- a/src/applications/phortune/controller/PhortuneAccountViewController.php +++ b/src/applications/phortune/controller/PhortuneAccountViewController.php @@ -152,45 +152,7 @@ final class PhortuneAccountViewController extends PhortuneController { ->withAccountPHIDs(array($account->getPHID())) ->execute(); - $rows = array(); - foreach ($charges as $charge) { - $rows[] = array( - $charge->getID(), - $charge->getCartPHID(), - $charge->getPaymentMethodPHID(), - PhortuneCurrency::newFromUSDCents($charge->getAmountInCents()) - ->formatForDisplay(), - $charge->getStatus(), - phabricator_datetime($charge->getDateCreated(), $viewer), - ); - } - - $charge_table = id(new AphrontTableView($rows)) - ->setHeaders( - array( - pht('Charge ID'), - pht('Cart'), - pht('Method'), - pht('Amount'), - pht('Status'), - pht('Created'), - )) - ->setColumnClasses( - array( - '', - '', - '', - 'wide right', - '', - '', - )); - - $header = id(new PHUIHeaderView()) - ->setHeader(pht('Charge History')); - - return id(new PHUIObjectBoxView()) - ->setHeader($header) - ->appendChild($charge_table); + return $this->buildChargesTable($charges); } private function buildAccountHistorySection(PhortuneAccount $account) { diff --git a/src/applications/phortune/controller/PhortuneAccountBuyController.php b/src/applications/phortune/controller/PhortuneCartCheckoutController.php similarity index 76% rename from src/applications/phortune/controller/PhortuneAccountBuyController.php rename to src/applications/phortune/controller/PhortuneCartCheckoutController.php index e279a84d41..bd2738e73d 100644 --- a/src/applications/phortune/controller/PhortuneAccountBuyController.php +++ b/src/applications/phortune/controller/PhortuneCartCheckoutController.php @@ -1,7 +1,7 @@ openTransaction(); $charge->save(); - // TODO: We should be setting some kind of status on the cart here. + $cart->setStatus(PhortuneCart::STATUS_PURCHASING); $cart->save(); $charge->saveTransaction(); $provider->applyCharge($method, $charge); - throw new Exception('Executed a charge! Your money is gone forever!'); - } - } - + $cart->setStatus(PhortuneCart::STATUS_PURCHASED); + $cart->save(); - $rows = array(); - $total = 0; - foreach ($cart->getPurchases() as $purchase) { - $rows[] = array( - pht('A Purchase'), - PhortuneCurrency::newFromUSDCents($purchase->getBasePriceInCents()) - ->formatForDisplay(), - $purchase->getQuantity(), - PhortuneCurrency::newFromUSDCents($purchase->getTotalPriceInCents()) - ->formatForDisplay(), - ); + $view_uri = $this->getApplicationURI('cart/'.$cart->getID().'/'); - $total += $purchase->getTotalPriceInCents(); + return id(new AphrontRedirectResponse())->setURI($view_uri); + } } - $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', - )); - - $cart_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Your Cart')) - ->setFormErrors($errors) - ->appendChild($table); + $cart_box = $this->buildCartContents($cart); + $cart_box->setFormErrors($errors); $title = pht('Buy Stuff'); diff --git a/src/applications/phortune/controller/PhortuneCartController.php b/src/applications/phortune/controller/PhortuneCartController.php new file mode 100644 index 0000000000..36d00d789d --- /dev/null +++ b/src/applications/phortune/controller/PhortuneCartController.php @@ -0,0 +1,52 @@ +getPurchases() as $purchase) { + $rows[] = array( + pht('A Purchase'), + 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); + } + +} diff --git a/src/applications/phortune/controller/PhortuneCartViewController.php b/src/applications/phortune/controller/PhortuneCartViewController.php new file mode 100644 index 0000000000..20265a902c --- /dev/null +++ b/src/applications/phortune/controller/PhortuneCartViewController.php @@ -0,0 +1,50 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $cart = id(new PhortuneCartQuery()) + ->setViewer($viewer) + ->withIDs(array($this->id)) + ->needPurchases(true) + ->executeOne(); + if (!$cart) { + return new Aphront404Response(); + } + + $cart_box = $this->buildCartContents($cart); + + $charges = id(new PhortuneChargeQuery()) + ->setViewer($viewer) + ->withCartPHIDs(array($cart->getPHID())) + ->execute(); + + $charges_table = $this->buildChargesTable($charges); + + $account = $cart->getAccount(); + + $crumbs = $this->buildApplicationCrumbs(); + $crumbs->addTextCrumb(pht('Cart')); + + return $this->buildApplicationPage( + array( + $crumbs, + $cart_box, + $charges_table, + ), + array( + 'title' => pht('Cart'), + )); + + } +} diff --git a/src/applications/phortune/controller/PhortuneController.php b/src/applications/phortune/controller/PhortuneController.php index 66ba0e6549..a8285124be 100644 --- a/src/applications/phortune/controller/PhortuneController.php +++ b/src/applications/phortune/controller/PhortuneController.php @@ -52,5 +52,52 @@ abstract class PhortuneController extends PhabricatorController { return $account; } + protected function buildChargesTable(array $charges) { + $request = $this->getRequest(); + $viewer = $request->getUser(); + + $rows = array(); + foreach ($charges as $charge) { + $rows[] = array( + $charge->getID(), + $charge->getCartPHID(), + $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('Charge ID'), + pht('Cart'), + pht('Provider'), + pht('Method'), + pht('Amount'), + pht('Status'), + pht('Created'), + )) + ->setColumnClasses( + array( + '', + '', + '', + '', + 'wide right', + '', + '', + )); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Charge History')); + + return id(new PHUIObjectBoxView()) + ->setHeader($header) + ->appendChild($charge_table); + } } diff --git a/src/applications/phortune/controller/PhortuneProductPurchaseController.php b/src/applications/phortune/controller/PhortuneProductPurchaseController.php index 14f8059105..285ca03cfb 100644 --- a/src/applications/phortune/controller/PhortuneProductPurchaseController.php +++ b/src/applications/phortune/controller/PhortuneProductPurchaseController.php @@ -39,6 +39,7 @@ final class PhortuneProductPurchaseController $cart = new PhortuneCart(); $cart->openTransaction(); + $cart->setStatus(PhortuneCart::STATUS_READY); $cart->setAccountPHID($account->getPHID()); $cart->setAuthorPHID($user->getPHID()); $cart->save(); @@ -57,7 +58,8 @@ final class PhortuneProductPurchaseController $cart->saveTransaction(); - $cart_uri = $this->getApplicationURI('/cart/'.$cart->getID().'/'); + $cart_id = $cart->getID(); + $cart_uri = $this->getApplicationURI('/cart/'.$cart_id.'/checkout/'); return id(new AphrontRedirectResponse())->setURI($cart_uri); } diff --git a/src/applications/phortune/controller/PhortuneProviderController.php b/src/applications/phortune/controller/PhortuneProviderController.php index 5389418311..96d2bc4157 100644 --- a/src/applications/phortune/controller/PhortuneProviderController.php +++ b/src/applications/phortune/controller/PhortuneProviderController.php @@ -56,7 +56,19 @@ final class PhortuneProviderController extends PhortuneController { public function loadCart($id) { - return id(new PhortuneCart()); + $request = $this->getRequest(); + $viewer = $request->getUser(); + + return id(new PhortuneCartQuery()) + ->setViewer($viewer) + ->needPurchases(true) + ->withIDs(array($id)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); } } diff --git a/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php b/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php index 55c9b82b97..ad55a4e32b 100644 --- a/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php +++ b/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php @@ -121,7 +121,7 @@ final class PhortunePaypalPaymentProvider extends PhortunePaymentProvider { 'cartID' => $cart->getID(), )); - $total_in_cents = $cart->getTotalInCents(); + $total_in_cents = $cart->getTotalPriceInCents(); $price = PhortuneCurrency::newFromUSDCents($total_in_cents); $result = $this diff --git a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php index b496cf91ce..0295f31256 100644 --- a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php +++ b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php @@ -111,11 +111,15 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider { 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'; @@ -139,7 +143,7 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider { 'cartID' => $cart->getID(), )); - $total_in_cents = $cart->getTotalInCents(); + $total_in_cents = $cart->getTotalPriceInCents(); $price = PhortuneCurrency::newFromUSDCents($total_in_cents); $params = array( @@ -153,7 +157,12 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider { 'fee_payer' => 'Payee', 'redirect_uri' => $return_uri, 'fallback_uri' => $cancel_uri, - 'auto_capture' => false, + + // NOTE: If we don't `auto_capture`, we might get a result back in + // either an "authorized" or a "reserved" state. We can't capture + // an "authorized" result, so just autocapture. + + 'auto_capture' => true, 'require_shipping' => 0, 'shipping_fee' => 0, 'charge_tax' => 0, @@ -163,18 +172,57 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider { $result = $wepay->request('checkout/create', $params); - // NOTE: We might want to store "$result->checkout_id" on the Cart. + // 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())->setURI($uri); case 'charge': + $checkout_id = $request->getInt('checkout_id'); + $params = array( + 'checkout_id' => $checkout_id, + ); - // NOTE: We get $_REQUEST['checkout_id'] here, but our parameters are - // dropped so we should stop depending on them or shove them into the - // URI. - - var_dump($_REQUEST); - break; + $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())->setURI($cart_uri); case 'cancel': var_dump($_REQUEST); break; diff --git a/src/applications/phortune/query/PhortuneChargeQuery.php b/src/applications/phortune/query/PhortuneChargeQuery.php index 60f2a03921..04ef7eae8b 100644 --- a/src/applications/phortune/query/PhortuneChargeQuery.php +++ b/src/applications/phortune/query/PhortuneChargeQuery.php @@ -6,6 +6,7 @@ final class PhortuneChargeQuery private $ids; private $phids; private $accountPHIDs; + private $cartPHIDs; public function withIDs(array $ids) { $this->ids = $ids; @@ -22,6 +23,11 @@ final class PhortuneChargeQuery return $this; } + public function withCartPHIDs(array $cart_phids) { + $this->cartPHIDs = $cart_phids; + return $this; + } + protected function loadPage() { $table = new PhortuneCharge(); $conn = $table->establishConnection('r'); @@ -83,6 +89,13 @@ final class PhortuneChargeQuery $this->accountPHIDs); } + if ($this->cartPHIDs !== null) { + $where[] = qsprintf( + $conn, + 'charge.cartPHID IN (%Ls)', + $this->cartPHIDs); + } + return $this->formatWhereClause($where); } diff --git a/src/applications/phortune/storage/PhortuneCart.php b/src/applications/phortune/storage/PhortuneCart.php index 1237fb23f2..eee9668bc0 100644 --- a/src/applications/phortune/storage/PhortuneCart.php +++ b/src/applications/phortune/storage/PhortuneCart.php @@ -3,8 +3,13 @@ final class PhortuneCart extends PhortuneDAO implements PhabricatorPolicyInterface { + const STATUS_READY = 'cart:ready'; + const STATUS_PURCHASING = 'cart:purchasing'; + const STATUS_PURCHASED = 'cart:purchased'; + protected $accountPHID; protected $authorPHID; + protected $status; protected $metadata; private $account = self::ATTACHABLE; @@ -24,10 +29,6 @@ final class PhortuneCart extends PhortuneDAO PhabricatorPHIDConstants::PHID_TYPE_CART); } - public function getTotalInCents() { - return 123; - } - public function attachPurchases(array $purchases) { assert_instances_of($purchases, 'PhortunePurchase'); $this->purchases = $purchases; diff --git a/src/applications/phortune/storage/PhortuneCharge.php b/src/applications/phortune/storage/PhortuneCharge.php index 64e3833db9..c65e89aef2 100644 --- a/src/applications/phortune/storage/PhortuneCharge.php +++ b/src/applications/phortune/storage/PhortuneCharge.php @@ -18,6 +18,7 @@ final class PhortuneCharge extends PhortuneDAO protected $accountPHID; protected $authorPHID; protected $cartPHID; + protected $paymentProviderKey; protected $paymentMethodPHID; protected $amountInCents; protected $status; -- 2.51.2