Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15407834
D20132.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
10 KB
Referenced Files
None
Subscribers
None
D20132.diff
View Options
diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,7 +9,7 @@
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
- 'core.pkg.css' => 'eab5ccaf',
+ 'core.pkg.css' => '08baca0c',
'core.pkg.js' => '5c737607',
'differential.pkg.css' => 'b8df73d4',
'differential.pkg.js' => '67c9ea4c',
@@ -30,7 +30,7 @@
'rsrc/css/aphront/notification.css' => '30240bd2',
'rsrc/css/aphront/panel-view.css' => '46923d46',
'rsrc/css/aphront/phabricator-nav-view.css' => 'f8a0c1bf',
- 'rsrc/css/aphront/table-view.css' => '76eda3f8',
+ 'rsrc/css/aphront/table-view.css' => 'daa1f9df',
'rsrc/css/aphront/tokenizer.css' => 'b52d0668',
'rsrc/css/aphront/tooltip.css' => 'e3f2412f',
'rsrc/css/aphront/typeahead-browse.css' => 'b7ed02d2',
@@ -519,7 +519,7 @@
'aphront-list-filter-view-css' => 'feb64255',
'aphront-multi-column-view-css' => 'fbc00ba3',
'aphront-panel-view-css' => '46923d46',
- 'aphront-table-view-css' => '76eda3f8',
+ 'aphront-table-view-css' => 'daa1f9df',
'aphront-tokenizer-control-css' => 'b52d0668',
'aphront-tooltip-css' => 'e3f2412f',
'aphront-typeahead-control-css' => '8779483d',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -5015,6 +5015,7 @@
'PhortuneCurrencySerializer' => 'applications/phortune/currency/PhortuneCurrencySerializer.php',
'PhortuneCurrencyTestCase' => 'applications/phortune/currency/__tests__/PhortuneCurrencyTestCase.php',
'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php',
+ 'PhortuneDisplayException' => 'applications/phortune/exception/PhortuneDisplayException.php',
'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
'PhortuneInvoiceView' => 'applications/phortune/view/PhortuneInvoiceView.php',
'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
@@ -11263,6 +11264,7 @@
'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer',
'PhortuneCurrencyTestCase' => 'PhabricatorTestCase',
'PhortuneDAO' => 'PhabricatorLiskDAO',
+ 'PhortuneDisplayException' => 'Exception',
'PhortuneErrCode' => 'PhortuneConstants',
'PhortuneInvoiceView' => 'AphrontTagView',
'PhortuneLandingController' => 'PhortuneController',
diff --git a/src/applications/fund/storage/FundBacker.php b/src/applications/fund/storage/FundBacker.php
--- a/src/applications/fund/storage/FundBacker.php
+++ b/src/applications/fund/storage/FundBacker.php
@@ -76,6 +76,7 @@
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
);
}
@@ -91,6 +92,8 @@
return $initiative->getPolicy($capability);
}
return PhabricatorPolicies::POLICY_NOONE;
+ case PhabricatorPolicyCapability::CAN_EDIT:
+ return PhabricatorPolicies::POLICY_NOONE;
}
}
diff --git a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
--- a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
+++ b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
@@ -73,6 +73,7 @@
$provider = $providers[$provider_id];
$errors = array();
+ $display_exception = null;
if ($request->isFormPost() && $request->getBool('isProviderForm')) {
$method = id(new PhortunePaymentMethod())
->setAccountPHID($account->getPHID())
@@ -107,14 +108,23 @@
}
if (!$errors) {
- $errors = $provider->createPaymentMethodFromRequest(
- $request,
- $method,
- $client_token);
+ try {
+ $provider->createPaymentMethodFromRequest(
+ $request,
+ $method,
+ $client_token);
+ } catch (PhortuneDisplayException $exception) {
+ $display_exception = $exception;
+ } catch (Exception $ex) {
+ $errors = array(
+ pht('There was an error adding this payment method:'),
+ $ex->getMessage(),
+ );
+ }
}
}
- if (!$errors) {
+ if (!$errors && !$display_exception) {
$method->save();
// If we added this method on a cart flow, return to the cart to
@@ -133,13 +143,17 @@
return id(new AphrontRedirectResponse())->setURI($next_uri);
} else {
- $dialog = id(new AphrontDialogView())
- ->setUser($viewer)
+ if ($display_exception) {
+ $dialog_body = $display_exception->getView();
+ } else {
+ $dialog_body = id(new PHUIInfoView())
+ ->setErrors($errors);
+ }
+
+ return $this->newDialog()
->setTitle(pht('Error Adding Payment Method'))
- ->appendChild(id(new PHUIInfoView())->setErrors($errors))
+ ->appendChild($dialog_body)
->addCancelButton($request->getRequestURI());
-
- return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
diff --git a/src/applications/phortune/exception/PhortuneDisplayException.php b/src/applications/phortune/exception/PhortuneDisplayException.php
new file mode 100644
--- /dev/null
+++ b/src/applications/phortune/exception/PhortuneDisplayException.php
@@ -0,0 +1,15 @@
+<?php
+
+final class PhortuneDisplayException
+ extends Exception {
+
+ public function setView($view) {
+ $this->view = $view;
+ return $this;
+ }
+
+ public function getView() {
+ return $this->view;
+ }
+
+}
diff --git a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
--- a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
+++ b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php
@@ -233,8 +233,6 @@
array $token) {
$this->loadStripeAPILibraries();
- $errors = array();
-
$secret_key = $this->getSecretKey();
$stripe_token = $token['stripeCardToken'];
@@ -253,7 +251,15 @@
// the card more than once. We create one Customer for each card;
// they do not map to PhortuneAccounts because we allow an account to
// have more than one active card.
- $customer = Stripe_Customer::create($params, $secret_key);
+ try {
+ $customer = Stripe_Customer::create($params, $secret_key);
+ } catch (Stripe_CardError $ex) {
+ $display_exception = $this->newDisplayExceptionFromCardError($ex);
+ if ($display_exception) {
+ throw $display_exception;
+ }
+ throw $ex;
+ }
$card = $info->card;
@@ -267,8 +273,6 @@
'stripe.customerID' => $customer->id,
'stripe.cardToken' => $stripe_token,
));
-
- return $errors;
}
public function renderCreatePaymentMethodForm(
@@ -383,4 +387,84 @@
require_once $root.'/externals/stripe-php/lib/Stripe.php';
}
+
+ private function newDisplayExceptionFromCardError(Stripe_CardError $ex) {
+ $body = $ex->getJSONBody();
+ if (!$body) {
+ return null;
+ }
+
+ $map = idx($body, 'error');
+ if (!$map) {
+ return null;
+ }
+
+ $view = array();
+
+ $message = idx($map, 'message');
+
+ $view[] = id(new PHUIInfoView())
+ ->setErrors(array($message));
+
+ $view[] = phutil_tag(
+ 'div',
+ array(
+ 'class' => 'mlt mlb',
+ ),
+ pht('Additional details about this error:'));
+
+ $rows = array();
+
+ $rows[] = array(
+ pht('Error Code'),
+ idx($map, 'code'),
+ );
+
+ $rows[] = array(
+ pht('Error Type'),
+ idx($map, 'type'),
+ );
+
+ $param = idx($map, 'param');
+ if (strlen($param)) {
+ $rows[] = array(
+ pht('Error Param'),
+ $param,
+ );
+ }
+
+ $decline_code = idx($map, 'decline_code');
+ if (strlen($decline_code)) {
+ $rows[] = array(
+ pht('Decline Code'),
+ $decline_code,
+ );
+ }
+
+ $doc_url = idx($map, 'doc_url');
+ if ($doc_url) {
+ $rows[] = array(
+ pht('Learn More'),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => $doc_url,
+ 'target' => '_blank',
+ ),
+ $doc_url),
+ );
+ }
+
+ $view[] = id(new AphrontTableView($rows))
+ ->setColumnClasses(
+ array(
+ 'header',
+ 'wide',
+ ));
+
+ return id(new PhortuneDisplayException(get_class($ex)))
+ ->setView($view);
+ }
+
+
}
diff --git a/src/applications/policy/filter/PhabricatorPolicyFilter.php b/src/applications/policy/filter/PhabricatorPolicyFilter.php
--- a/src/applications/policy/filter/PhabricatorPolicyFilter.php
+++ b/src/applications/policy/filter/PhabricatorPolicyFilter.php
@@ -175,9 +175,10 @@
if (!in_array($capability, $object_capabilities)) {
throw new Exception(
pht(
- "Testing for capability '%s' on an object which does ".
- "not have that capability!",
- $capability));
+ 'Testing for capability "%s" on an object ("%s") which does '.
+ 'not support that capability.',
+ $capability,
+ get_class($object)));
}
$policy = $this->getObjectPolicy($object, $capability);
diff --git a/webroot/rsrc/css/aphront/table-view.css b/webroot/rsrc/css/aphront/table-view.css
--- a/webroot/rsrc/css/aphront/table-view.css
+++ b/webroot/rsrc/css/aphront/table-view.css
@@ -45,16 +45,20 @@
background: inherit;
}
-.aphront-table-view th {
+.aphront-table-view th,
+.aphront-table-view td.header {
font-weight: bold;
white-space: nowrap;
color: {$bluetext};
- text-shadow: 0 1px 0 white;
font-weight: bold;
- border-bottom: 1px solid {$thinblueborder};
+ text-shadow: 0 1px 0 white;
background-color: {$lightbluebackground};
}
+.aphront-table-view th {
+ border-bottom: 1px solid {$thinblueborder};
+}
+
th.aphront-table-view-sortable-selected {
background-color: {$greybackground};
}
@@ -74,12 +78,8 @@
}
.aphront-table-view td.header {
- padding: 4px 8px;
- white-space: nowrap;
text-align: right;
- color: {$bluetext};
- font-weight: bold;
- vertical-align: top;
+ border-right: 1px solid {$thinblueborder};
}
.aphront-table-view td {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 19, 7:53 PM (5 h, 8 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7709464
Default Alt Text
D20132.diff (10 KB)
Attached To
Mode
D20132: Improve UI/UX when users try to add an invalid card with Stripe
Attached
Detach File
Event Timeline
Log In to Comment