2013-04-12 17:10:22 +02:00
|
|
|
<?php
|
|
|
|
|
2014-07-23 19:36:25 +02:00
|
|
|
final class PhortuneCartCheckoutController
|
|
|
|
extends PhortuneCartController {
|
2013-04-12 17:10:22 +02:00
|
|
|
|
|
|
|
private $id;
|
|
|
|
|
|
|
|
public function willProcessRequest(array $data) {
|
|
|
|
$this->id = $data['id'];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processRequest() {
|
|
|
|
$request = $this->getRequest();
|
2014-07-23 19:36:12 +02:00
|
|
|
$viewer = $request->getUser();
|
2013-04-12 17:10:22 +02:00
|
|
|
|
2014-07-23 19:34:08 +02:00
|
|
|
$cart = id(new PhortuneCartQuery())
|
2014-07-23 19:36:12 +02:00
|
|
|
->setViewer($viewer)
|
2013-04-12 17:10:22 +02:00
|
|
|
->withIDs(array($this->id))
|
2014-07-23 19:34:08 +02:00
|
|
|
->needPurchases(true)
|
2013-04-12 17:10:22 +02:00
|
|
|
->executeOne();
|
2014-07-23 19:34:08 +02:00
|
|
|
if (!$cart) {
|
2013-04-12 17:10:22 +02:00
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
2014-10-06 19:36:43 +02:00
|
|
|
$cancel_uri = $cart->getCancelURI();
|
|
|
|
|
|
|
|
switch ($cart->getStatus()) {
|
|
|
|
case PhortuneCart::STATUS_BUILDING:
|
|
|
|
return $this->newDialog()
|
|
|
|
->setTitle(pht('Incomplete Cart'))
|
|
|
|
->appendParagraph(
|
|
|
|
pht(
|
|
|
|
'The application that created this cart did not finish putting '.
|
|
|
|
'products in it. You can not checkout with an incomplete '.
|
|
|
|
'cart.'))
|
|
|
|
->addCancelButton($cancel_uri);
|
|
|
|
case PhortuneCart::STATUS_READY:
|
|
|
|
// This is the expected, normal state for a cart that's ready for
|
|
|
|
// checkout.
|
|
|
|
break;
|
|
|
|
case PhortuneCart::STATUS_CHARGED:
|
|
|
|
// TODO: This is really bad (we took your money and at least partially
|
|
|
|
// failed to fulfill your order) and should have better steps forward.
|
|
|
|
|
|
|
|
return $this->newDialog()
|
|
|
|
->setTitle(pht('Purchase Failed'))
|
|
|
|
->appendParagraph(
|
|
|
|
pht(
|
|
|
|
'This cart was charged but the purchase could not be '.
|
|
|
|
'completed.'))
|
|
|
|
->addCancelButton($cancel_uri);
|
|
|
|
case PhortuneCart::STATUS_PURCHASED:
|
|
|
|
return id(new AphrontRedirectResponse())->setURI($cart->getDetailURI());
|
|
|
|
default:
|
|
|
|
throw new Exception(
|
|
|
|
pht(
|
|
|
|
'Unknown cart status "%s"!',
|
|
|
|
$cart->getStatus()));
|
|
|
|
}
|
|
|
|
|
2014-07-23 19:34:08 +02:00
|
|
|
$account = $cart->getAccount();
|
|
|
|
$account_uri = $this->getApplicationURI($account->getID().'/');
|
2013-04-25 18:45:07 +02:00
|
|
|
|
2014-07-23 19:36:12 +02:00
|
|
|
$methods = id(new PhortunePaymentMethodQuery())
|
|
|
|
->setViewer($viewer)
|
|
|
|
->withAccountPHIDs(array($account->getPHID()))
|
2014-08-11 21:07:35 +02:00
|
|
|
->withStatuses(array(PhortunePaymentMethod::STATUS_ACTIVE))
|
2014-07-23 19:36:12 +02:00
|
|
|
->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())
|
2014-08-11 21:07:35 +02:00
|
|
|
->setPaymentProviderKey($provider->getProviderKey())
|
2014-07-23 19:36:12 +02:00
|
|
|
->setPaymentMethodPHID($method->getPHID())
|
2014-10-06 19:26:48 +02:00
|
|
|
->setAmountAsCurrency($cart->getTotalPriceAsCurrency())
|
2014-07-23 19:36:12 +02:00
|
|
|
->setStatus(PhortuneCharge::STATUS_PENDING);
|
|
|
|
|
|
|
|
$charge->openTransaction();
|
|
|
|
$charge->save();
|
|
|
|
|
2014-07-23 19:36:25 +02:00
|
|
|
$cart->setStatus(PhortuneCart::STATUS_PURCHASING);
|
2014-07-23 19:36:12 +02:00
|
|
|
$cart->save();
|
|
|
|
$charge->saveTransaction();
|
|
|
|
|
|
|
|
$provider->applyCharge($method, $charge);
|
|
|
|
|
2014-10-06 19:36:43 +02:00
|
|
|
$cart->didApplyCharge($charge);
|
2014-07-23 19:36:12 +02:00
|
|
|
|
2014-10-06 19:36:43 +02:00
|
|
|
$done_uri = $cart->getDoneURI();
|
|
|
|
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
2014-07-23 19:36:25 +02:00
|
|
|
}
|
2013-04-25 18:45:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-23 19:36:25 +02:00
|
|
|
$cart_box = $this->buildCartContents($cart);
|
|
|
|
$cart_box->setFormErrors($errors);
|
2013-04-25 18:45:07 +02:00
|
|
|
|
|
|
|
$title = pht('Buy Stuff');
|
|
|
|
|
|
|
|
if (!$methods) {
|
|
|
|
$method_control = id(new AphrontFormStaticControl())
|
|
|
|
->setLabel(pht('Payment Method'))
|
|
|
|
->setValue(
|
|
|
|
phutil_tag('em', array(), pht('No payment methods configured.')));
|
|
|
|
} else {
|
|
|
|
$method_control = id(new AphrontFormRadioButtonControl())
|
|
|
|
->setLabel(pht('Payment Method'))
|
|
|
|
->setName('paymentMethodID')
|
|
|
|
->setValue($request->getInt('paymentMethodID'));
|
|
|
|
foreach ($methods as $method) {
|
|
|
|
$method_control->addButton(
|
|
|
|
$method->getID(),
|
2014-08-18 22:15:21 +02:00
|
|
|
$method->getFullDisplayName(),
|
2013-04-25 18:45:07 +02:00
|
|
|
$method->getDescription());
|
|
|
|
}
|
|
|
|
}
|
2013-04-12 17:10:22 +02:00
|
|
|
|
2014-07-23 19:36:12 +02:00
|
|
|
$method_control->setError($e_method);
|
|
|
|
|
2013-04-12 17:10:22 +02:00
|
|
|
$payment_method_uri = $this->getApplicationURI(
|
2014-08-11 21:07:35 +02:00
|
|
|
$account->getID().'/card/new/');
|
2013-04-12 17:10:22 +02:00
|
|
|
|
|
|
|
$form = id(new AphrontFormView())
|
2014-07-23 19:36:12 +02:00
|
|
|
->setUser($viewer)
|
2013-05-06 20:44:24 +02:00
|
|
|
->appendChild($method_control);
|
|
|
|
|
|
|
|
$add_providers = PhortunePaymentProvider::getProvidersForAddPaymentMethod();
|
|
|
|
if ($add_providers) {
|
|
|
|
$new_method = phutil_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'class' => 'button grey',
|
|
|
|
'href' => $payment_method_uri,
|
|
|
|
'sigil' => 'workflow',
|
|
|
|
),
|
|
|
|
pht('Add New Payment Method'));
|
|
|
|
$form->appendChild(
|
|
|
|
id(new AphrontFormMarkupControl())
|
|
|
|
->setValue($new_method));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($methods || $add_providers) {
|
|
|
|
$form
|
|
|
|
->appendChild(
|
|
|
|
id(new AphrontFormSubmitControl())
|
2014-06-09 20:36:49 +02:00
|
|
|
->setValue(pht('Submit Payment'))
|
2013-05-06 20:44:24 +02:00
|
|
|
->setDisabled(!$methods));
|
|
|
|
}
|
|
|
|
|
|
|
|
$provider_form = null;
|
|
|
|
|
|
|
|
$pay_providers = PhortunePaymentProvider::getProvidersForOneTimePayment();
|
|
|
|
if ($pay_providers) {
|
|
|
|
$one_time_options = array();
|
|
|
|
foreach ($pay_providers as $provider) {
|
|
|
|
$one_time_options[] = $provider->renderOneTimePaymentButton(
|
|
|
|
$account,
|
|
|
|
$cart,
|
2014-07-23 19:36:12 +02:00
|
|
|
$viewer);
|
2013-05-06 20:44:24 +02:00
|
|
|
}
|
|
|
|
|
2014-07-23 19:36:37 +02:00
|
|
|
$one_time_options = phutil_tag(
|
|
|
|
'div',
|
|
|
|
array(
|
|
|
|
'class' => 'phortune-payment-onetime-list',
|
|
|
|
),
|
|
|
|
$one_time_options);
|
|
|
|
|
2013-08-26 20:53:11 +02:00
|
|
|
$provider_form = new PHUIFormLayoutView();
|
2013-05-06 20:44:24 +02:00
|
|
|
$provider_form->appendChild(
|
2013-04-12 17:10:22 +02:00
|
|
|
id(new AphrontFormMarkupControl())
|
2013-05-06 20:44:24 +02:00
|
|
|
->setLabel('Pay With')
|
|
|
|
->setValue($one_time_options));
|
|
|
|
}
|
2013-04-12 17:10:22 +02:00
|
|
|
|
2014-07-13 18:18:50 +02:00
|
|
|
$payment_box = id(new PHUIObjectBoxView())
|
|
|
|
->setHeaderText(pht('Choose Payment Method'))
|
|
|
|
->appendChild($form)
|
|
|
|
->appendChild($provider_form);
|
|
|
|
|
|
|
|
$crumbs = $this->buildApplicationCrumbs();
|
|
|
|
$crumbs->addTextCrumb($title);
|
|
|
|
|
2013-04-12 17:10:22 +02:00
|
|
|
return $this->buildApplicationPage(
|
2013-04-25 18:45:07 +02:00
|
|
|
array(
|
2014-07-13 18:18:50 +02:00
|
|
|
$crumbs,
|
|
|
|
$cart_box,
|
|
|
|
$payment_box,
|
2013-04-25 18:45:07 +02:00
|
|
|
),
|
2013-04-12 17:10:22 +02:00
|
|
|
array(
|
|
|
|
'title' => $title,
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|