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();
|
2014-10-07 23:41:59 +02:00
|
|
|
$merchant = $cart->getMerchant();
|
2014-10-06 19:36:43 +02:00
|
|
|
|
|
|
|
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:
|
2014-10-09 13:30:47 +02:00
|
|
|
case PhortuneCart::STATUS_PURCHASING:
|
|
|
|
case PhortuneCart::STATUS_HOLD:
|
2014-10-10 20:29:13 +02:00
|
|
|
case PhortuneCart::STATUS_REVIEW:
|
2014-10-06 19:36:43 +02:00
|
|
|
case PhortuneCart::STATUS_PURCHASED:
|
2014-10-09 13:30:47 +02:00
|
|
|
// For these states, kick the user to the order page to give them
|
|
|
|
// information and options.
|
2014-10-06 19:36:43 +02:00
|
|
|
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-10-07 23:41:59 +02:00
|
|
|
->withMerchantPHIDs(array($merchant->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();
|
|
|
|
|
2014-10-06 23:20:40 +02:00
|
|
|
$charge = $cart->willApplyCharge($viewer, $provider, $method);
|
2014-10-09 02:23:02 +02:00
|
|
|
|
|
|
|
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'));
|
|
|
|
}
|
|
|
|
|
2014-10-06 19:36:43 +02:00
|
|
|
$cart->didApplyCharge($charge);
|
2014-07-23 19:36:12 +02:00
|
|
|
|
2014-10-10 01:58:26 +02:00
|
|
|
$done_uri = $cart->getCheckoutURI();
|
2014-10-06 19:36:43 +02:00
|
|
|
return id(new AphrontRedirectResponse())->setURI($done_uri);
|
2014-07-23 19:36:25 +02:00
|
|
|
}
|
2013-04-25 18:45:07 +02:00
|
|
|
}
|
|
|
|
|
2014-10-09 00:33:25 +02:00
|
|
|
$cart_table = $this->buildCartContentTable($cart);
|
|
|
|
|
|
|
|
$cart_box = id(new PHUIObjectBoxView())
|
|
|
|
->setFormErrors($errors)
|
|
|
|
->setHeaderText(pht('Cart Contents'))
|
|
|
|
->appendChild($cart_table);
|
2013-04-25 18:45:07 +02:00
|
|
|
|
2014-10-10 01:59:03 +02:00
|
|
|
$title = $cart->getName();
|
2013-04-25 18:45:07 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-10-07 23:41:59 +02:00
|
|
|
$account_id = $account->getID();
|
|
|
|
|
|
|
|
$payment_method_uri = $this->getApplicationURI("{$account_id}/card/new/");
|
|
|
|
$payment_method_uri = new PhutilURI($payment_method_uri);
|
|
|
|
$payment_method_uri->setQueryParams(
|
|
|
|
array(
|
|
|
|
'merchantID' => $merchant->getID(),
|
|
|
|
'cartID' => $cart->getID(),
|
|
|
|
));
|
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);
|
|
|
|
|
2014-10-07 23:41:59 +02:00
|
|
|
$add_providers = $this->loadCreatePaymentMethodProvidersForMerchant(
|
|
|
|
$merchant);
|
2013-05-06 20:44:24 +02:00
|
|
|
if ($add_providers) {
|
2014-10-08 00:07:01 +02:00
|
|
|
$new_method = javelin_tag(
|
2013-05-06 20:44:24 +02:00
|
|
|
'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) {
|
2014-10-06 23:19:08 +02:00
|
|
|
$submit = id(new AphrontFormSubmitControl())
|
|
|
|
->setValue(pht('Submit Payment'))
|
|
|
|
->setDisabled(!$methods);
|
|
|
|
|
|
|
|
if ($cart->getCancelURI() !== null) {
|
|
|
|
$submit->addCancelButton($cart->getCancelURI());
|
|
|
|
}
|
|
|
|
|
|
|
|
$form->appendChild($submit);
|
2013-05-06 20:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
$provider_form = null;
|
|
|
|
|
2014-10-07 23:41:59 +02:00
|
|
|
$pay_providers = $this->loadOneTimePaymentProvidersForMerchant($merchant);
|
2013-05-06 20:44:24 +02:00
|
|
|
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();
|
2014-10-10 01:59:03 +02:00
|
|
|
$crumbs->addTextCrumb(pht('Checkout'));
|
2014-07-13 18:18:50 +02:00
|
|
|
$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,
|
|
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|