[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/phortune/controller/ -> PhortunePaymentMethodCreateController.php (source)

   1  <?php
   2  
   3  final class PhortunePaymentMethodCreateController
   4    extends PhortuneController {
   5  
   6    private $accountID;
   7  
   8    public function willProcessRequest(array $data) {
   9      $this->accountID = $data['accountID'];
  10    }
  11  
  12    public function processRequest() {
  13      $request = $this->getRequest();
  14      $viewer = $request->getUser();
  15  
  16      $account = id(new PhortuneAccountQuery())
  17        ->setViewer($viewer)
  18        ->withIDs(array($this->accountID))
  19        ->executeOne();
  20      if (!$account) {
  21        return new Aphront404Response();
  22      }
  23  
  24      $merchant = id(new PhortuneMerchantQuery())
  25        ->setViewer($viewer)
  26        ->withIDs(array($request->getInt('merchantID')))
  27        ->executeOne();
  28      if (!$merchant) {
  29        return new Aphront404Response();
  30      }
  31  
  32      $cart_id = $request->getInt('cartID');
  33      if ($cart_id) {
  34        $cancel_uri = $this->getApplicationURI("cart/{$cart_id}/checkout/");
  35      } else {
  36        $cancel_uri = $this->getApplicationURI($account->getID().'/');
  37      }
  38  
  39      $providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant);
  40      if (!$providers) {
  41        throw new Exception(
  42          'There are no payment providers enabled that can add payment '.
  43          'methods.');
  44      }
  45  
  46      $provider_id = $request->getInt('providerID');
  47      if (empty($providers[$provider_id])) {
  48        $choices = array();
  49        foreach ($providers as $provider) {
  50          $choices[] = $this->renderSelectProvider($provider);
  51        }
  52  
  53        $content = phutil_tag(
  54          'div',
  55          array(
  56            'class' => 'phortune-payment-method-list',
  57          ),
  58          $choices);
  59  
  60        return $this->newDialog()
  61          ->setRenderDialogAsDiv(true)
  62          ->setTitle(pht('Add Payment Method'))
  63          ->appendParagraph(pht('Choose a payment method to add:'))
  64          ->appendChild($content)
  65          ->addCancelButton($cancel_uri);
  66      }
  67  
  68      $provider = $providers[$provider_id];
  69  
  70      $errors = array();
  71      if ($request->isFormPost() && $request->getBool('isProviderForm')) {
  72        $method = id(new PhortunePaymentMethod())
  73          ->setAccountPHID($account->getPHID())
  74          ->setAuthorPHID($viewer->getPHID())
  75          ->setMerchantPHID($merchant->getPHID())
  76          ->setProviderPHID($provider->getProviderConfig()->getPHID())
  77          ->setStatus(PhortunePaymentMethod::STATUS_ACTIVE);
  78  
  79        if (!$errors) {
  80          $errors = $this->processClientErrors(
  81            $provider,
  82            $request->getStr('errors'));
  83        }
  84  
  85        if (!$errors) {
  86          $client_token_raw = $request->getStr('token');
  87          $client_token = json_decode($client_token_raw, true);
  88          if (!is_array($client_token)) {
  89            $errors[] = pht(
  90              'There was an error decoding token information submitted by the '.
  91              'client. Expected a JSON-encoded token dictionary, received: %s.',
  92              nonempty($client_token_raw, pht('nothing')));
  93          } else {
  94            if (!$provider->validateCreatePaymentMethodToken($client_token)) {
  95              $errors[] = pht(
  96                'There was an error with the payment token submitted by the '.
  97                'client. Expected a valid dictionary, received: %s.',
  98                $client_token_raw);
  99            }
 100          }
 101          if (!$errors) {
 102            $errors = $provider->createPaymentMethodFromRequest(
 103              $request,
 104              $method,
 105              $client_token);
 106          }
 107        }
 108  
 109        if (!$errors) {
 110          $method->save();
 111  
 112          // If we added this method on a cart flow, return to the cart to
 113          // check out.
 114          if ($cart_id) {
 115            $next_uri = $this->getApplicationURI(
 116              "cart/{$cart_id}/checkout/?paymentMethodID=".$method->getID());
 117          } else {
 118            $account_uri = $this->getApplicationURI($account->getID().'/');
 119            $next_uri = new PhutilURI($account_uri);
 120            $next_uri->setFragment('payment');
 121          }
 122  
 123          return id(new AphrontRedirectResponse())->setURI($next_uri);
 124        } else {
 125          $dialog = id(new AphrontDialogView())
 126            ->setUser($viewer)
 127            ->setTitle(pht('Error Adding Payment Method'))
 128            ->appendChild(id(new AphrontErrorView())->setErrors($errors))
 129            ->addCancelButton($request->getRequestURI());
 130  
 131          return id(new AphrontDialogResponse())->setDialog($dialog);
 132        }
 133      }
 134  
 135      $form = $provider->renderCreatePaymentMethodForm($request, $errors);
 136  
 137      $form
 138        ->setUser($viewer)
 139        ->setAction($request->getRequestURI())
 140        ->setWorkflow(true)
 141        ->addHiddenInput('providerID', $provider_id)
 142        ->addHiddenInput('cartID', $request->getInt('cartID'))
 143        ->addHiddenInput('isProviderForm', true)
 144        ->appendChild(
 145          id(new AphrontFormSubmitControl())
 146            ->setValue(pht('Add Payment Method'))
 147            ->addCancelButton($cancel_uri));
 148  
 149      $box = id(new PHUIObjectBoxView())
 150        ->setHeaderText($provider->getPaymentMethodDescription())
 151        ->setForm($form);
 152  
 153      $crumbs = $this->buildApplicationCrumbs();
 154      $crumbs->addTextCrumb(pht('Add Payment Method'));
 155  
 156      return $this->buildApplicationPage(
 157        array(
 158          $crumbs,
 159          $box,
 160        ),
 161        array(
 162          'title' => $provider->getPaymentMethodDescription(),
 163        ));
 164    }
 165  
 166    private function renderSelectProvider(
 167      PhortunePaymentProvider $provider) {
 168  
 169      $request = $this->getRequest();
 170      $viewer = $request->getUser();
 171  
 172      $description = $provider->getPaymentMethodDescription();
 173      $icon_uri = $provider->getPaymentMethodIcon();
 174      $details = $provider->getPaymentMethodProviderDescription();
 175  
 176      $this->requireResource('phortune-css');
 177  
 178      $icon = id(new PHUIIconView())
 179        ->setSpriteSheet(PHUIIconView::SPRITE_LOGIN)
 180        ->setSpriteIcon($provider->getPaymentMethodIcon());
 181  
 182      $button = id(new PHUIButtonView())
 183        ->setSize(PHUIButtonView::BIG)
 184        ->setColor(PHUIButtonView::GREY)
 185        ->setIcon($icon)
 186        ->setText($description)
 187        ->setSubtext($details)
 188        ->setMetadata(array('disableWorkflow' => true));
 189  
 190      $form = id(new AphrontFormView())
 191        ->setUser($viewer)
 192        ->setAction($request->getRequestURI())
 193        ->addHiddenInput('providerID', $provider->getProviderConfig()->getID())
 194        ->appendChild($button);
 195  
 196      return $form;
 197    }
 198  
 199    private function processClientErrors(
 200      PhortunePaymentProvider $provider,
 201      $client_errors_raw) {
 202  
 203      $errors = array();
 204  
 205      $client_errors = json_decode($client_errors_raw, true);
 206      if (!is_array($client_errors)) {
 207        $errors[] = pht(
 208          'There was an error decoding error information submitted by the '.
 209          'client. Expected a JSON-encoded list of error codes, received: %s.',
 210          nonempty($client_errors_raw, pht('nothing')));
 211      }
 212  
 213      foreach (array_unique($client_errors) as $key => $client_error) {
 214        $client_errors[$key] = $provider->translateCreatePaymentMethodErrorCode(
 215          $client_error);
 216      }
 217  
 218      foreach (array_unique($client_errors) as $client_error) {
 219        switch ($client_error) {
 220          case PhortuneErrCode::ERR_CC_INVALID_NUMBER:
 221            $message = pht(
 222              'The card number you entered is not a valid card number. Check '.
 223              'that you entered it correctly.');
 224            break;
 225          case PhortuneErrCode::ERR_CC_INVALID_CVC:
 226            $message = pht(
 227              'The CVC code you entered is not a valid CVC code. Check that '.
 228              'you entered it correctly. The CVC code is a 3-digit or 4-digit '.
 229              'numeric code which usually appears on the back of the card.');
 230            break;
 231          case PhortuneErrCode::ERR_CC_INVALID_EXPIRY:
 232            $message = pht(
 233              'The card expiration date is not a valid expiration date. Check '.
 234              'that you entered it correctly. You can not add an expired card '.
 235              'as a payment method.');
 236            break;
 237          default:
 238            $message = $provider->getCreatePaymentMethodErrorMessage(
 239              $client_error);
 240            if (!$message) {
 241              $message = pht(
 242                "There was an unexpected error ('%s') processing payment ".
 243                "information.",
 244                $client_error);
 245  
 246              phlog($message);
 247            }
 248            break;
 249        }
 250  
 251        $errors[$client_error] = $message;
 252      }
 253  
 254      return $errors;
 255    }
 256  
 257  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1