mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 16:22:43 +01:00
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
This commit is contained in:
parent
4c0f15b94b
commit
d6eb1c67e7
18 changed files with 274 additions and 105 deletions
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE {$NAMESPACE}_phortune.phortune_cart
|
||||
ADD status VARCHAR(32) NOT NULL COLLATE utf8_bin;
|
|
@ -0,0 +1,2 @@
|
|||
UPDATE {$NAMESPACE}_phortune.phortune_cart
|
||||
SET status = 'cart:ready' WHERE status = '';
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE {$NAMESPACE}_phortune.phortune_charge
|
||||
ADD paymentProviderKey VARCHAR(128) NOT NULL COLLATE utf8_bin
|
||||
AFTER cartPHID;
|
|
@ -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;
|
|
@ -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',
|
||||
|
|
|
@ -41,7 +41,10 @@ final class PhabricatorPhortuneApplication extends PhabricatorApplication {
|
|||
),
|
||||
'buy/(?P<productID>\d+)/' => 'PhortuneProductPurchaseController',
|
||||
),
|
||||
'cart/(?P<id>\d+)/' => 'PhortuneAccountBuyController',
|
||||
'cart/(?P<id>\d+)/' => array(
|
||||
'' => 'PhortuneCartViewController',
|
||||
'checkout/' => 'PhortuneCartCheckoutController',
|
||||
),
|
||||
'account/' => array(
|
||||
'' => 'PhortuneAccountListController',
|
||||
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneAccountEditController',
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneAccountBuyController
|
||||
extends PhortuneController {
|
||||
final class PhortuneCartCheckoutController
|
||||
extends PhortuneCartController {
|
||||
|
||||
private $id;
|
||||
|
||||
|
@ -64,60 +64,23 @@ final class PhortuneAccountBuyController
|
|||
$charge->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();
|
||||
|
||||
$view_uri = $this->getApplicationURI('cart/'.$cart->getID().'/');
|
||||
|
||||
return id(new AphrontRedirectResponse())->setURI($view_uri);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$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(),
|
||||
);
|
||||
|
||||
$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',
|
||||
));
|
||||
|
||||
$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');
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
abstract class PhortuneCartController
|
||||
extends PhortuneController {
|
||||
|
||||
protected function buildCartContents(PhortuneCart $cart) {
|
||||
|
||||
$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(),
|
||||
);
|
||||
|
||||
$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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
final class PhortuneCartViewController
|
||||
extends PhortuneCartController {
|
||||
|
||||
private $id;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->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'),
|
||||
));
|
||||
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
$checkout = $wepay->request('checkout', $params);
|
||||
if ($checkout->reference_id != $cart->getPHID()) {
|
||||
throw new Exception(
|
||||
pht('Checkout reference ID does not match cart PHID!'));
|
||||
}
|
||||
|
||||
var_dump($_REQUEST);
|
||||
break;
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -18,6 +18,7 @@ final class PhortuneCharge extends PhortuneDAO
|
|||
protected $accountPHID;
|
||||
protected $authorPHID;
|
||||
protected $cartPHID;
|
||||
protected $paymentProviderKey;
|
||||
protected $paymentMethodPHID;
|
||||
protected $amountInCents;
|
||||
protected $status;
|
||||
|
|
Loading…
Reference in a new issue