Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14063515
D10666.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D10666.diff
View Options
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -518,7 +518,7 @@
*
* @return AphrontDialogView New dialog.
*/
- protected function newDialog() {
+ public function newDialog() {
$submit_uri = new PhutilURI($this->getRequest()->getRequestURI());
$submit_uri = $submit_uri->getPath();
diff --git a/src/applications/phortune/controller/PhortuneCartCheckoutController.php b/src/applications/phortune/controller/PhortuneCartCheckoutController.php
--- a/src/applications/phortune/controller/PhortuneCartCheckoutController.php
+++ b/src/applications/phortune/controller/PhortuneCartCheckoutController.php
@@ -111,7 +111,20 @@
$provider = $method->buildPaymentProvider();
$charge = $cart->willApplyCharge($viewer, $provider, $method);
- $provider->applyCharge($method, $charge);
+
+ try {
+ $provider->applyCharge($method, $charge);
+ } catch (Exception $ex) {
+ $cart->didFailCharge($charge);
+ return $this->newDialog()
+ ->setTitle(pht('Charge Failed'))
+ ->appendParagraph(
+ pht(
+ 'Unable to make payment: %s',
+ $ex->getMessage()))
+ ->addCancelButton($cart->getCheckoutURI(), pht('Continue'));
+ }
+
$cart->didApplyCharge($charge);
$done_uri = $cart->getDoneURI();
diff --git a/src/applications/phortune/provider/PhortunePayPalPaymentProvider.php b/src/applications/phortune/provider/PhortunePayPalPaymentProvider.php
--- a/src/applications/phortune/provider/PhortunePayPalPaymentProvider.php
+++ b/src/applications/phortune/provider/PhortunePayPalPaymentProvider.php
@@ -339,9 +339,27 @@
// difficult for now and we can't reasonably just fail these charges.
var_dump($result);
-
die();
- break;
+
+ $success = false; // TODO: <----
+
+ // TODO: Clean this up once that mess up there ^^^^^ gets cleaned up.
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ if ($success) {
+ $cart->didApplyCharge($charge);
+ $response = id(new AphrontRedirectResponse())->setURI(
+ $cart->getDoneURI());
+ } else {
+ $cart->didFailCharge($charge);
+
+ $response = $controller
+ ->newDialog()
+ ->setTitle(pht('Charge Failed'))
+ ->addCancelButton($cart->getCheckoutURI(), pht('Continue'));
+ }
+ unset($unguarded);
+
+ return $response;
case 'cancel':
var_dump($_REQUEST);
break;
diff --git a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
--- a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
+++ b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
@@ -145,7 +145,7 @@
}
public function getPaymentMethodDescription() {
- return pht('Credit Card or Bank Account');
+ return pht('Credit or Debit Card');
}
public function getPaymentMethodIcon() {
@@ -286,10 +286,10 @@
$params = array(
'account_id' => $this->getWePayAccountID(),
- 'short_description' => 'Services', // TODO
+ 'short_description' => $cart->getName(),
'type' => 'SERVICE',
'amount' => $price->formatBareValue(),
- 'long_description' => 'Services', // TODO
+ 'long_description' => $cart->getName(),
'reference_id' => $cart->getPHID(),
'app_fee' => 0,
'fee_payer' => 'Payee',
@@ -305,7 +305,10 @@
'shipping_fee' => 0,
'charge_tax' => 0,
'mode' => 'regular',
- 'funding_sources' => 'bank,cc',
+
+ // TODO: We could accept bank accounts but the hold/capture rules
+ // are not quite clear. Just accept credit cards for now.
+ 'funding_sources' => 'cc',
);
$charge = $cart->willApplyCharge($viewer, $this);
@@ -322,6 +325,11 @@
->setIsExternal(true)
->setURI($uri);
case 'charge':
+ if ($cart->getStatus() !== PhortuneCart::STATUS_PURCHASING) {
+ return id(new AphrontRedirectResponse())
+ ->setURI($cart->getCheckoutURI());
+ }
+
$checkout_id = $request->getInt('checkout_id');
$params = array(
'checkout_id' => $checkout_id,
@@ -333,24 +341,41 @@
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();
- $cart->didApplyCharge($charge);
+ switch ($checkout->state) {
+ case 'authorized':
+ case 'reserved':
+ case 'captured':
+ // TODO: Are these all really "done" states, and not "hold"
+ // states? Cards and bank accounts both come back as "authorized"
+ // on the staging environment. Figure out what happens in
+ // production?
+
+ $cart->didApplyCharge($charge);
+
+ $response = id(new AphrontRedirectResponse())->setURI(
+ $cart->getDoneURI());
+ break;
+ default:
+ // It's not clear if we can ever get here on the web workflow,
+ // WePay doesn't seem to return back to us after a failure (the
+ // workflow dead-ends instead).
+
+ $cart->didFailCharge($charge);
+
+ $response = $controller
+ ->newDialog()
+ ->setTitle(pht('Charge Failed'))
+ ->appendParagraph(
+ pht(
+ 'Unable to make payment (checkout state is "%s").',
+ $checkout->state))
+ ->addCancelButton($cart->getCheckoutURI(), pht('Continue'));
+ break;
+ }
unset($unguarded);
- return id(new AphrontRedirectResponse())
- ->setURI($cart->getDoneURI());
+ return $response;
case 'cancel':
// TODO: I don't know how it's possible to cancel out of a WePay
// charge workflow.
diff --git a/src/applications/phortune/storage/PhortuneCart.php b/src/applications/phortune/storage/PhortuneCart.php
--- a/src/applications/phortune/storage/PhortuneCart.php
+++ b/src/applications/phortune/storage/PhortuneCart.php
@@ -146,6 +146,37 @@
return $this;
}
+ public function didFailCharge(PhortuneCharge $charge) {
+ $charge->setStatus(PhortuneCharge::STATUS_FAILED);
+
+ $this->openTransaction();
+ $this->beginReadLocking();
+
+ $copy = clone $this;
+ $copy->reload();
+
+ if ($copy->getStatus() !== self::STATUS_PURCHASING) {
+ throw new Exception(
+ pht(
+ 'Cart has wrong status ("%s") to call didFailCharge(), '.
+ 'expected "%s".',
+ $copy->getStatus(),
+ self::STATUS_PURCHASING));
+ }
+
+ $charge->save();
+
+ // Move the cart back into STATUS_READY so the user can try
+ // making the purchase again.
+ $this->setStatus(self::STATUS_READY)->save();
+
+ $this->endReadLocking();
+ $this->saveTransaction();
+
+ return $this;
+ }
+
+
public function willRefundCharge(
PhabricatorUser $actor,
PhortunePaymentProvider $provider,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 19, 6:50 PM (10 h, 23 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6749759
Default Alt Text
D10666.diff (7 KB)
Attached To
Mode
D10666: Handle Phortune charge failures cleanly
Attached
Detach File
Event Timeline
Log In to Comment