mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-19 18:28:39 +01:00
Phortune Charges
Summary: Ref T2787. Makes charges a real object, allows providers to apply them. We are now (just barely) capable of stealing users' money. Test Plan: {F179584} Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10002
This commit is contained in:
parent
6ec1f35870
commit
4c0f15b94b
12 changed files with 322 additions and 23 deletions
16
resources/sql/autopatches/20140721.phortune.3.charge.sql
Normal file
16
resources/sql/autopatches/20140721.phortune.3.charge.sql
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
CREATE TABLE {$NAMESPACE}_phortune.phortune_charge (
|
||||||
|
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
accountPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
authorPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
cartPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
paymentMethodPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||||
|
amountInCents INT NOT NULL,
|
||||||
|
status VARCHAR(32) NOT NULL COLLATE utf8_bin,
|
||||||
|
metadata LONGTEXT NOT NULL COLLATE utf8_bin,
|
||||||
|
dateCreated INT UNSIGNED NOT NULL,
|
||||||
|
dateModified INT UNSIGNED NOT NULL,
|
||||||
|
UNIQUE KEY `key_phid` (phid),
|
||||||
|
KEY `key_cart` (cartPHID),
|
||||||
|
KEY `key_account` (accountPHID)
|
||||||
|
) ENGINE=InnoDB, COLLATE utf8_general_ci;
|
|
@ -2498,6 +2498,7 @@ phutil_register_library_map(array(
|
||||||
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
|
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
|
||||||
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
|
||||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||||
|
'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php',
|
||||||
'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php',
|
'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php',
|
||||||
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
|
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
|
||||||
'PhortuneCreditCardForm' => 'applications/phortune/view/PhortuneCreditCardForm.php',
|
'PhortuneCreditCardForm' => 'applications/phortune/view/PhortuneCreditCardForm.php',
|
||||||
|
@ -5382,8 +5383,13 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPolicyInterface',
|
'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhortuneCharge' => 'PhortuneDAO',
|
'PhortuneCharge' => array(
|
||||||
|
'PhortuneDAO',
|
||||||
|
'PhabricatorPolicyInterface',
|
||||||
|
),
|
||||||
|
'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'PhortuneController' => 'PhabricatorController',
|
'PhortuneController' => 'PhabricatorController',
|
||||||
|
'PhortuneCurrency' => 'Phobject',
|
||||||
'PhortuneCurrencyTestCase' => 'PhabricatorTestCase',
|
'PhortuneCurrencyTestCase' => 'PhabricatorTestCase',
|
||||||
'PhortuneDAO' => 'PhabricatorLiskDAO',
|
'PhortuneDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhortuneErrCode' => 'PhortuneConstants',
|
'PhortuneErrCode' => 'PhortuneConstants',
|
||||||
|
|
|
@ -11,10 +11,10 @@ final class PhortuneAccountBuyController
|
||||||
|
|
||||||
public function processRequest() {
|
public function processRequest() {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
$cart = id(new PhortuneCartQuery())
|
$cart = id(new PhortuneCartQuery())
|
||||||
->setViewer($user)
|
->setViewer($viewer)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($this->id))
|
||||||
->needPurchases(true)
|
->needPurchases(true)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
|
@ -25,6 +25,56 @@ final class PhortuneAccountBuyController
|
||||||
$account = $cart->getAccount();
|
$account = $cart->getAccount();
|
||||||
$account_uri = $this->getApplicationURI($account->getID().'/');
|
$account_uri = $this->getApplicationURI($account->getID().'/');
|
||||||
|
|
||||||
|
$methods = id(new PhortunePaymentMethodQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withAccountPHIDs(array($account->getPHID()))
|
||||||
|
->withStatus(PhortunePaymentMethodQuery::STATUS_OPEN)
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
$e_method = null;
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
|
||||||
|
// Require CAN_EDIT on the cart to actually make purchases.
|
||||||
|
|
||||||
|
PhabricatorPolicyFilter::requireCapability(
|
||||||
|
$viewer,
|
||||||
|
$cart,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$method_id = $request->getInt('paymentMethodID');
|
||||||
|
$method = idx($methods, $method_id);
|
||||||
|
if (!$method) {
|
||||||
|
$e_method = pht('Required');
|
||||||
|
$errors[] = pht('You must choose a payment method.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$provider = $method->buildPaymentProvider();
|
||||||
|
|
||||||
|
$charge = id(new PhortuneCharge())
|
||||||
|
->setAccountPHID($account->getPHID())
|
||||||
|
->setCartPHID($cart->getPHID())
|
||||||
|
->setAuthorPHID($viewer->getPHID())
|
||||||
|
->setPaymentMethodPHID($method->getPHID())
|
||||||
|
->setAmountInCents($cart->getTotalPriceInCents())
|
||||||
|
->setStatus(PhortuneCharge::STATUS_PENDING);
|
||||||
|
|
||||||
|
$charge->openTransaction();
|
||||||
|
$charge->save();
|
||||||
|
|
||||||
|
// TODO: We should be setting some kind of status on the cart here.
|
||||||
|
$cart->save();
|
||||||
|
$charge->saveTransaction();
|
||||||
|
|
||||||
|
$provider->applyCharge($method, $charge);
|
||||||
|
|
||||||
|
throw new Exception('Executed a charge! Your money is gone forever!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$rows = array();
|
$rows = array();
|
||||||
$total = 0;
|
$total = 0;
|
||||||
foreach ($cart->getPurchases() as $purchase) {
|
foreach ($cart->getPurchases() as $purchase) {
|
||||||
|
@ -66,20 +116,11 @@ final class PhortuneAccountBuyController
|
||||||
|
|
||||||
$cart_box = id(new PHUIObjectBoxView())
|
$cart_box = id(new PHUIObjectBoxView())
|
||||||
->setHeaderText(pht('Your Cart'))
|
->setHeaderText(pht('Your Cart'))
|
||||||
|
->setFormErrors($errors)
|
||||||
->appendChild($table);
|
->appendChild($table);
|
||||||
|
|
||||||
$title = pht('Buy Stuff');
|
$title = pht('Buy Stuff');
|
||||||
|
|
||||||
|
|
||||||
$methods = id(new PhortunePaymentMethodQuery())
|
|
||||||
->setViewer($user)
|
|
||||||
->withAccountPHIDs(array($account->getPHID()))
|
|
||||||
->withStatus(PhortunePaymentMethodQuery::STATUS_OPEN)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$method_control = id(new AphrontFormRadioButtonControl())
|
|
||||||
->setLabel(pht('Payment Method'));
|
|
||||||
|
|
||||||
if (!$methods) {
|
if (!$methods) {
|
||||||
$method_control = id(new AphrontFormStaticControl())
|
$method_control = id(new AphrontFormStaticControl())
|
||||||
->setLabel(pht('Payment Method'))
|
->setLabel(pht('Payment Method'))
|
||||||
|
@ -98,11 +139,13 @@ final class PhortuneAccountBuyController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$method_control->setError($e_method);
|
||||||
|
|
||||||
$payment_method_uri = $this->getApplicationURI(
|
$payment_method_uri = $this->getApplicationURI(
|
||||||
$account->getID().'/paymentmethod/edit/');
|
$account->getID().'/paymentmethod/edit/');
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
$form = id(new AphrontFormView())
|
||||||
->setUser($user)
|
->setUser($viewer)
|
||||||
->appendChild($method_control);
|
->appendChild($method_control);
|
||||||
|
|
||||||
$add_providers = PhortunePaymentProvider::getProvidersForAddPaymentMethod();
|
$add_providers = PhortunePaymentProvider::getProvidersForAddPaymentMethod();
|
||||||
|
@ -137,7 +180,7 @@ final class PhortuneAccountBuyController
|
||||||
$one_time_options[] = $provider->renderOneTimePaymentButton(
|
$one_time_options[] = $provider->renderOneTimePaymentButton(
|
||||||
$account,
|
$account,
|
||||||
$cart,
|
$cart,
|
||||||
$user);
|
$viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
$provider_form = new PHUIFormLayoutView();
|
$provider_form = new PHUIFormLayoutView();
|
||||||
|
|
|
@ -56,6 +56,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
|
|
||||||
$payment_methods = $this->buildPaymentMethodsSection($account);
|
$payment_methods = $this->buildPaymentMethodsSection($account);
|
||||||
$purchase_history = $this->buildPurchaseHistorySection($account);
|
$purchase_history = $this->buildPurchaseHistorySection($account);
|
||||||
|
$charge_history = $this->buildChargeHistorySection($account);
|
||||||
$account_history = $this->buildAccountHistorySection($account);
|
$account_history = $this->buildAccountHistorySection($account);
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
|
@ -68,6 +69,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
$object_box,
|
$object_box,
|
||||||
$payment_methods,
|
$payment_methods,
|
||||||
$purchase_history,
|
$purchase_history,
|
||||||
|
$charge_history,
|
||||||
$account_history,
|
$account_history,
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
|
@ -141,6 +143,56 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
->setHeader($header);
|
->setHeader($header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function buildChargeHistorySection(PhortuneAccount $account) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$charges = id(new PhortuneChargeQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->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);
|
||||||
|
}
|
||||||
|
|
||||||
private function buildAccountHistorySection(PhortuneAccount $account) {
|
private function buildAccountHistorySection(PhortuneAccount $account) {
|
||||||
$request = $this->getRequest();
|
$request = $this->getRequest();
|
||||||
$user = $request->getUser();
|
$user = $request->getUser();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhortuneCurrency {
|
final class PhortuneCurrency extends Phobject {
|
||||||
|
|
||||||
private $value;
|
private $value;
|
||||||
private $currency;
|
private $currency;
|
||||||
|
@ -52,6 +52,18 @@ final class PhortuneCurrency {
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
public static function newFromUSDCents($cents) {
|
public static function newFromUSDCents($cents) {
|
||||||
if (!is_int($cents)) {
|
if (!is_int($cents)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
|
|
|
@ -96,6 +96,19 @@ abstract class PhortunePaymentProvider {
|
||||||
abstract public function canHandlePaymentMethod(
|
abstract public function canHandlePaymentMethod(
|
||||||
PhortunePaymentMethod $method);
|
PhortunePaymentMethod $method);
|
||||||
|
|
||||||
|
final public function applyCharge(
|
||||||
|
PhortunePaymentMethod $payment_method,
|
||||||
|
PhortuneCharge $charge) {
|
||||||
|
|
||||||
|
$charge->setStatus(PhortuneCharge::STATUS_CHARGING);
|
||||||
|
$charge->save();
|
||||||
|
|
||||||
|
$this->executeCharge($payment_method, $charge);
|
||||||
|
|
||||||
|
$charge->setStatus(PhortuneCharge::STATUS_CHARGED);
|
||||||
|
$charge->save();
|
||||||
|
}
|
||||||
|
|
||||||
abstract protected function executeCharge(
|
abstract protected function executeCharge(
|
||||||
PhortunePaymentMethod $payment_method,
|
PhortunePaymentMethod $payment_method,
|
||||||
PhortuneCharge $charge);
|
PhortuneCharge $charge);
|
||||||
|
|
|
@ -40,6 +40,9 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
PhortunePaymentMethod $method,
|
PhortunePaymentMethod $method,
|
||||||
PhortuneCharge $charge) {
|
PhortuneCharge $charge) {
|
||||||
|
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
||||||
|
|
||||||
$secret_key = $this->getSecretKey();
|
$secret_key = $this->getSecretKey();
|
||||||
$params = array(
|
$params = array(
|
||||||
'amount' => $charge->getAmountInCents(),
|
'amount' => $charge->getAmountInCents(),
|
||||||
|
|
|
@ -49,6 +49,7 @@ final class PhortuneCartQuery
|
||||||
$account = idx($accounts, $cart->getAccountPHID());
|
$account = idx($accounts, $cart->getAccountPHID());
|
||||||
if (!$account) {
|
if (!$account) {
|
||||||
unset($carts[$key]);
|
unset($carts[$key]);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
$cart->attachAccount($account);
|
$cart->attachAccount($account);
|
||||||
}
|
}
|
||||||
|
|
93
src/applications/phortune/query/PhortuneChargeQuery.php
Normal file
93
src/applications/phortune/query/PhortuneChargeQuery.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhortuneChargeQuery
|
||||||
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
|
private $ids;
|
||||||
|
private $phids;
|
||||||
|
private $accountPHIDs;
|
||||||
|
|
||||||
|
public function withIDs(array $ids) {
|
||||||
|
$this->ids = $ids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withPHIDs(array $phids) {
|
||||||
|
$this->phids = $phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function withAccountPHIDs(array $account_phids) {
|
||||||
|
$this->accountPHIDs = $account_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadPage() {
|
||||||
|
$table = new PhortuneCharge();
|
||||||
|
$conn = $table->establishConnection('r');
|
||||||
|
|
||||||
|
$rows = queryfx_all(
|
||||||
|
$conn,
|
||||||
|
'SELECT charge.* FROM %T charge %Q %Q %Q',
|
||||||
|
$table->getTableName(),
|
||||||
|
$this->buildWhereClause($conn),
|
||||||
|
$this->buildOrderClause($conn),
|
||||||
|
$this->buildLimitClause($conn));
|
||||||
|
|
||||||
|
return $table->loadAllFromArray($rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function willFilterPage(array $charges) {
|
||||||
|
$accounts = id(new PhortuneAccountQuery())
|
||||||
|
->setViewer($this->getViewer())
|
||||||
|
->setParentQuery($this)
|
||||||
|
->withPHIDs(mpull($charges, 'getAccountPHID'))
|
||||||
|
->execute();
|
||||||
|
$accounts = mpull($accounts, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($charges as $key => $charge) {
|
||||||
|
$account = idx($accounts, $charge->getAccountPHID());
|
||||||
|
if (!$account) {
|
||||||
|
unset($charges[$key]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$charge->attachAccount($account);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $charges;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildWhereClause(AphrontDatabaseConnection $conn) {
|
||||||
|
$where = array();
|
||||||
|
|
||||||
|
$where[] = $this->buildPagingClause($conn);
|
||||||
|
|
||||||
|
if ($this->ids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'charge.id IN (%Ld)',
|
||||||
|
$this->ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->phids !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'charge.phid IN (%Ls)',
|
||||||
|
$this->phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->accountPHIDs !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn,
|
||||||
|
'charge.accountPHID IN (%Ls)',
|
||||||
|
$this->accountPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->formatWhereClause($where);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQueryApplicationClass() {
|
||||||
|
return 'PhabricatorApplicationPhortune';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -38,16 +38,18 @@ final class PhortunePurchaseQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willFilterPage(array $purchases) {
|
protected function willFilterPage(array $purchases) {
|
||||||
$carts = id(new PhabricatorObjectQuery())
|
$carts = id(new PhortuneCartQuery())
|
||||||
->setViewer($this->getViewer())
|
->setViewer($this->getViewer())
|
||||||
->setParentQuery($this)
|
->setParentQuery($this)
|
||||||
->withPHIDs(mpull($purchases, 'getCartPHID'))
|
->withPHIDs(mpull($purchases, 'getCartPHID'))
|
||||||
->execute();
|
->execute();
|
||||||
|
$carts = mpull($carts, null, 'getPHID');
|
||||||
|
|
||||||
foreach ($purchases as $key => $purchase) {
|
foreach ($purchases as $key => $purchase) {
|
||||||
$cart = idx($carts, $purchase->getCartPHID());
|
$cart = idx($carts, $purchase->getCartPHID());
|
||||||
if (!$cart) {
|
if (!$cart) {
|
||||||
unset($purchases[$key]);
|
unset($purchases[$key]);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
$purchase->attachCart($cart);
|
$purchase->attachCart($cart);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,16 @@ final class PhortuneCart extends PhortuneDAO
|
||||||
return $this->assertAttached($this->account);
|
return $this->assertAttached($this->account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTotalPriceInCents() {
|
||||||
|
$prices = array();
|
||||||
|
foreach ($this->getPurchases() as $purchase) {
|
||||||
|
$prices[] = PhortuneCurrency::newFromUSDCents(
|
||||||
|
$purchase->getTotalPriceInCents());
|
||||||
|
}
|
||||||
|
|
||||||
|
return PhortuneCurrency::newFromList($prices)->getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A charge is a charge (or credit) against an account and represents an actual
|
* A charge is a charge (or credit) against an account and represents an actual
|
||||||
* transfer of funds. Each charge is normally associated with a product, but a
|
* transfer of funds. Each charge is normally associated with a cart, but a
|
||||||
* product may have multiple charges. For example, a subscription may have
|
* cart may have multiple charges. For example, a product may have a failed
|
||||||
* monthly charges, or a product may have a failed charge followed by a
|
* charge followed by a successful charge.
|
||||||
* successful charge.
|
|
||||||
*/
|
*/
|
||||||
final class PhortuneCharge extends PhortuneDAO {
|
final class PhortuneCharge extends PhortuneDAO
|
||||||
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
const STATUS_PENDING = 'charge:pending';
|
const STATUS_PENDING = 'charge:pending';
|
||||||
const STATUS_AUTHORIZED = 'charge:authorized';
|
const STATUS_AUTHORIZED = 'charge:authorized';
|
||||||
|
@ -16,12 +16,15 @@ final class PhortuneCharge extends PhortuneDAO {
|
||||||
const STATUS_FAILED = 'charge:failed';
|
const STATUS_FAILED = 'charge:failed';
|
||||||
|
|
||||||
protected $accountPHID;
|
protected $accountPHID;
|
||||||
protected $purchasePHID;
|
protected $authorPHID;
|
||||||
|
protected $cartPHID;
|
||||||
protected $paymentMethodPHID;
|
protected $paymentMethodPHID;
|
||||||
protected $amountInCents;
|
protected $amountInCents;
|
||||||
protected $status;
|
protected $status;
|
||||||
protected $metadata = array();
|
protected $metadata = array();
|
||||||
|
|
||||||
|
private $account = self::ATTACHABLE;
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
@ -36,4 +39,49 @@ final class PhortuneCharge extends PhortuneDAO {
|
||||||
PhabricatorPHIDConstants::PHID_TYPE_CHRG);
|
PhabricatorPHIDConstants::PHID_TYPE_CHRG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function didReadData() {
|
||||||
|
// The payment processing code is strict about types.
|
||||||
|
$this->amountInCents = (int)$this->amountInCents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetadataValue($key, $default = null) {
|
||||||
|
return idx($this->metadata, $key, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMetadataValue($key, $value) {
|
||||||
|
$this->metadata[$key] = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAccount() {
|
||||||
|
return $this->assertAttached($this->account);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attachAccount(PhortuneAccount $account) {
|
||||||
|
$this->account = $account;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function getCapabilities() {
|
||||||
|
return array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPolicy($capability) {
|
||||||
|
return $this->getAccount()->getPolicy($capability);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
|
return $this->getAccount()->hasAutomaticCapability($capability, $viewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function describeAutomaticCapability($capability) {
|
||||||
|
return pht('Charges inherit the policies of the associated account.');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue