private function processClientErrors(PhortunePaymentProvider $provider, $client_errors_raw)
 {
     $errors = array();
     $client_errors = json_decode($client_errors_raw, true);
     if (!is_array($client_errors)) {
         $errors[] = pht('There was an error decoding error information submitted by the ' . 'client. Expected a JSON-encoded list of error codes, received: %s.', nonempty($client_errors_raw, pht('nothing')));
     }
     foreach (array_unique($client_errors) as $key => $client_error) {
         $client_errors[$key] = $provider->translateCreatePaymentMethodErrorCode($client_error);
     }
     foreach (array_unique($client_errors) as $client_error) {
         switch ($client_error) {
             case PhortuneErrCode::ERR_CC_INVALID_NUMBER:
                 $message = pht('The card number you entered is not a valid card number. Check ' . 'that you entered it correctly.');
                 break;
             case PhortuneErrCode::ERR_CC_INVALID_CVC:
                 $message = pht('The CVC code you entered is not a valid CVC code. Check that ' . 'you entered it correctly. The CVC code is a 3-digit or 4-digit ' . 'numeric code which usually appears on the back of the card.');
                 break;
             case PhortuneErrCode::ERR_CC_INVALID_EXPIRY:
                 $message = pht('The card expiration date is not a valid expiration date. Check ' . 'that you entered it correctly. You can not add an expired card ' . 'as a payment method.');
                 break;
             default:
                 $message = $provider->getCreatePaymentMethodErrorMessage($client_error);
                 if (!$message) {
                     $message = pht("There was an unexpected error ('%s') processing payment " . "information.", $client_error);
                     phlog($message);
                 }
                 break;
         }
         $errors[$client_error] = $message;
     }
     return $errors;
 }
 public function canRespondToControllerAction($action)
 {
     switch ($action) {
         case 'checkout':
         case 'charge':
         case 'cancel':
             return true;
     }
     return parent::canRespondToControllerAction();
 }
Exemplo n.º 3
0
 public function buildPaymentProvider()
 {
     $providers = PhortunePaymentProvider::getAllProviders();
     $accept = array();
     foreach ($providers as $provider) {
         if ($provider->canHandlePaymentMethod($this)) {
             $accept[] = $provider;
         }
     }
     if (!$accept) {
         throw new PhortuneNoPaymentProviderException($this);
     }
     if (count($accept) > 1) {
         throw new PhortuneMultiplePaymentProvidersException($this, $accept);
     }
     return head($accept);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $user = $request->getUser();
     // NOTE: This use of digests to identify payment providers is because
     // payment provider keys don't necessarily have restrictions on what they
     // contain (so they might have stuff that's not safe to put in URIs), and
     // using digests prevents errors with URI encoding.
     $provider = PhortunePaymentProvider::getProviderByDigest($this->digest);
     if (!$provider) {
         throw new Exception('Invalid payment provider digest!');
     }
     if (!$provider->canRespondToControllerAction($this->getAction())) {
         return new Aphront404Response();
     }
     $response = $provider->processControllerRequest($this, $request);
     if ($response instanceof AphrontResponse) {
         return $response;
     }
     $title = 'Phortune';
     return $this->buildApplicationPage($response, array('title' => $title));
 }
Exemplo n.º 5
0
 public function willRefundCharge(PhabricatorUser $actor, PhortunePaymentProvider $provider, PhortuneCharge $charge, PhortuneCurrency $amount)
 {
     if (!$amount->isPositive()) {
         throw new Exception(pht('Trying to refund non-positive amount of money!'));
     }
     if ($amount->isGreaterThan($charge->getAmountRefundableAsCurrency())) {
         throw new Exception(pht('Trying to refund more money than remaining on charge!'));
     }
     if ($charge->getRefundedChargePHID()) {
         throw new Exception(pht('Trying to refund a refund!'));
     }
     if ($charge->getStatus() !== PhortuneCharge::STATUS_CHARGED && $charge->getStatus() !== PhortuneCharge::STATUS_HOLD) {
         throw new Exception(pht('Trying to refund an uncharged charge!'));
     }
     $refund_charge = PhortuneCharge::initializeNewCharge()->setAccountPHID($this->getAccount()->getPHID())->setCartPHID($this->getPHID())->setAuthorPHID($actor->getPHID())->setMerchantPHID($this->getMerchant()->getPHID())->setProviderPHID($provider->getProviderConfig()->getPHID())->setPaymentMethodPHID($charge->getPaymentMethodPHID())->setRefundedChargePHID($charge->getPHID())->setAmountAsCurrency($amount->negate());
     $charge->openTransaction();
     $charge->beginReadLocking();
     $copy = clone $charge;
     $copy->reload();
     if ($copy->getRefundingPHID() !== null) {
         throw new Exception(pht('Trying to refund a charge which is already refunding!'));
     }
     $refund_charge->save();
     $charge->setRefundingPHID($refund_charge->getPHID());
     $charge->save();
     $charge->endReadLocking();
     $charge->saveTransaction();
     return $refund_charge;
 }
 private function processChooseClassRequest(AphrontRequest $request, PhortuneMerchant $merchant, array $current_map)
 {
     $viewer = $request->getUser();
     $providers = PhortunePaymentProvider::getAllProviders();
     $v_class = null;
     $errors = array();
     if ($request->isFormPost()) {
         $v_class = $request->getStr('class');
         if (!isset($providers[$v_class])) {
             $errors[] = pht('You must select a valid provider type.');
         }
     }
     $merchant_id = $merchant->getID();
     $cancel_uri = $this->getApplicationURI("merchant/{$merchant_id}/");
     if (!$v_class) {
         $v_class = key($providers);
     }
     $panel_classes = id(new AphrontFormRadioButtonControl())->setName('class')->setValue($v_class);
     $providers = msort($providers, 'getConfigureName');
     foreach ($providers as $class => $provider) {
         $disabled = isset($current_map[$class]);
         if ($disabled) {
             $description = phutil_tag('em', array(), pht('This merchant already has a payment account configured ' . 'with this provider.'));
         } else {
             $description = $provider->getConfigureDescription();
         }
         $panel_classes->addButton($class, $provider->getConfigureName(), $description, null, $disabled);
     }
     $form = id(new AphrontFormView())->setUser($viewer)->addHiddenInput('merchantID', $merchant->getID())->appendRemarkupInstructions(pht('Choose the type of payment provider to add:'))->appendChild($panel_classes)->appendChild(id(new AphrontFormSubmitControl())->setValue(pht('Continue'))->addCancelButton($cancel_uri));
     $title = pht('Add Payment Provider');
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($merchant->getName(), $cancel_uri);
     $crumbs->addTextCrumb($title);
     $box = id(new PHUIObjectBoxView())->setHeaderText($title)->setFormErrors($errors)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $box), array('title' => $title));
 }
 public function testGetAllProviders()
 {
     PhortunePaymentProvider::getAllProviders();
     $this->assertTrue(true);
 }
 public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $cart = id(new PhortuneCartQuery())->setViewer($viewer)->withIDs(array($this->id))->needPurchases(true)->executeOne();
     if (!$cart) {
         return new Aphront404Response();
     }
     $account = $cart->getAccount();
     $account_uri = $this->getApplicationURI($account->getID() . '/');
     $methods = id(new PhortunePaymentMethodQuery())->setViewer($viewer)->withAccountPHIDs(array($account->getPHID()))->withStatuses(array(PhortunePaymentMethod::STATUS_ACTIVE))->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())->setPaymentProviderKey($provider->getProviderKey())->setPaymentMethodPHID($method->getPHID())->setAmountInCents($cart->getTotalPriceInCents())->setStatus(PhortuneCharge::STATUS_PENDING);
             $charge->openTransaction();
             $charge->save();
             $cart->setStatus(PhortuneCart::STATUS_PURCHASING);
             $cart->save();
             $charge->saveTransaction();
             $provider->applyCharge($method, $charge);
             $cart->setStatus(PhortuneCart::STATUS_PURCHASED);
             $cart->save();
             $view_uri = $this->getApplicationURI('cart/' . $cart->getID() . '/');
             return id(new AphrontRedirectResponse())->setURI($view_uri);
         }
     }
     $cart_box = $this->buildCartContents($cart);
     $cart_box->setFormErrors($errors);
     $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(), $method->getFullDisplayName(), $method->getDescription());
         }
     }
     $method_control->setError($e_method);
     $payment_method_uri = $this->getApplicationURI($account->getID() . '/card/new/');
     $form = id(new AphrontFormView())->setUser($viewer)->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())->setValue(pht('Submit Payment'))->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, $viewer);
         }
         $one_time_options = phutil_tag('div', array('class' => 'phortune-payment-onetime-list'), $one_time_options);
         $provider_form = new PHUIFormLayoutView();
         $provider_form->appendChild(id(new AphrontFormMarkupControl())->setLabel('Pay With')->setValue($one_time_options));
     }
     $payment_box = id(new PHUIObjectBoxView())->setHeaderText(pht('Choose Payment Method'))->appendChild($form)->appendChild($provider_form);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($title);
     return $this->buildApplicationPage(array($crumbs, $cart_box, $payment_box), array('title' => $title));
 }