@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix a Phortune billing issue where subscription autopay could charge disabled cards

Summary:
See support email. There's nothing tricky here, we were just missing a check. The different parts of this got built at different times so I think this was simply overlooked.

Also add a redundant check just to future-proof this and be on the safe side.

Test Plan: Used `bin/phortune invoice` to charge a pact subscription. After deleting the card, the charge failed with an appropriate error.

Reviewers: amckinley

Differential Revision: https://secure.phabricator.com/D19020

+23 -17
+8 -17
src/applications/phortune/query/PhortunePaymentMethodQuery.php
··· 34 34 return $this; 35 35 } 36 36 37 + public function newResultObject() { 38 + return new PhortunePaymentMethod(); 39 + } 40 + 37 41 protected function loadPage() { 38 - $table = new PhortunePaymentMethod(); 39 - $conn = $table->establishConnection('r'); 40 - 41 - $rows = queryfx_all( 42 - $conn, 43 - 'SELECT * FROM %T %Q %Q %Q', 44 - $table->getTableName(), 45 - $this->buildWhereClause($conn), 46 - $this->buildOrderClause($conn), 47 - $this->buildLimitClause($conn)); 48 - 49 - return $table->loadAllFromArray($rows); 42 + return $this->loadStandardPage($this->newResultObject()); 50 43 } 51 44 52 45 protected function willFilterPage(array $methods) { ··· 106 99 return $methods; 107 100 } 108 101 109 - protected function buildWhereClause(AphrontDatabaseConnection $conn) { 110 - $where = array(); 102 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 103 + $where = parent::buildWhereClauseParts($conn); 111 104 112 105 if ($this->ids !== null) { 113 106 $where[] = qsprintf( ··· 144 137 $this->statuses); 145 138 } 146 139 147 - $where[] = $this->buildPagingClause($conn); 148 - 149 - return $this->formatWhereClause($where); 140 + return $where; 150 141 } 151 142 152 143 public function getQueryApplicationClass() {
+7
src/applications/phortune/storage/PhortuneCart.php
··· 118 118 ->setAmountAsCurrency($this->getTotalPriceAsCurrency()); 119 119 120 120 if ($method) { 121 + if (!$method->isActive()) { 122 + throw new Exception( 123 + pht( 124 + 'Attempting to apply a charge using an inactive '. 125 + 'payment method ("%s")!', 126 + $method->getPHID())); 127 + } 121 128 $charge->setPaymentMethodPHID($method->getPHID()); 122 129 } 123 130
+4
src/applications/phortune/storage/PhortunePaymentMethod.php
··· 128 128 return $month.'/'.$year; 129 129 } 130 130 131 + public function isActive() { 132 + return ($this->getStatus() === self::STATUS_ACTIVE); 133 + } 134 + 131 135 132 136 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 133 137
+4
src/applications/phortune/worker/PhortuneSubscriptionWorker.php
··· 141 141 $method = id(new PhortunePaymentMethodQuery()) 142 142 ->setViewer($viewer) 143 143 ->withPHIDs(array($subscription->getDefaultPaymentMethodPHID())) 144 + ->withStatuses( 145 + array( 146 + PhortunePaymentMethod::STATUS_ACTIVE, 147 + )) 144 148 ->executeOne(); 145 149 if (!$method) { 146 150 $issues[] = pht(