diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'cd54f10c', + 'core.pkg.css' => 'd9fa6161', 'core.pkg.js' => '23d653bb', 'darkconsole.pkg.js' => '8ab24e01', 'differential.pkg.css' => '4c3242f8', @@ -83,7 +83,7 @@ 'rsrc/css/application/pholio/pholio-edit.css' => '3ad9d1ee', 'rsrc/css/application/pholio/pholio-inline-comments.css' => '8e545e49', 'rsrc/css/application/pholio/pholio.css' => '95174bdd', - 'rsrc/css/application/phortune/phortune-credit-card-form.css' => 'b25b4beb', + 'rsrc/css/application/phortune/phortune-credit-card-form.css' => '8391eb02', 'rsrc/css/application/phortune/phortune.css' => '9149f103', 'rsrc/css/application/phrequent/phrequent.css' => 'ffc185ad', 'rsrc/css/application/phriction/phriction-document-css.css' => '0d16bc9a', @@ -129,7 +129,7 @@ 'rsrc/css/phui/phui-document.css' => '620b1eec', 'rsrc/css/phui/phui-feed-story.css' => 'c9f3a0b5', 'rsrc/css/phui/phui-fontkit.css' => '4394f216', - 'rsrc/css/phui/phui-form-view.css' => '8b78a986', + 'rsrc/css/phui/phui-form-view.css' => '76f0b086', 'rsrc/css/phui/phui-form.css' => 'f535f938', 'rsrc/css/phui/phui-header-view.css' => '083669db', 'rsrc/css/phui/phui-icon.css' => 'd35aa857', @@ -242,7 +242,6 @@ 'rsrc/image/checker_dark.png' => 'd8e65881', 'rsrc/image/checker_light.png' => 'a0155918', 'rsrc/image/checker_lighter.png' => 'd5da91b6', - 'rsrc/image/credit_cards.png' => '72b8ede8', 'rsrc/image/darkload.gif' => '1ffd3ec6', 'rsrc/image/divot.png' => '94dded62', 'rsrc/image/examples/hero.png' => '979a86ae', @@ -766,7 +765,7 @@ 'pholio-edit-css' => '3ad9d1ee', 'pholio-inline-comments-css' => '8e545e49', 'phortune-credit-card-form' => '2290aeef', - 'phortune-credit-card-form-css' => 'b25b4beb', + 'phortune-credit-card-form-css' => '8391eb02', 'phortune-css' => '9149f103', 'phrequent-css' => 'ffc185ad', 'phriction-document-css' => '0d16bc9a', @@ -784,7 +783,7 @@ 'phui-font-icon-base-css' => '3dad2ae3', 'phui-fontkit-css' => '4394f216', 'phui-form-css' => 'f535f938', - 'phui-form-view-css' => '8b78a986', + 'phui-form-view-css' => '76f0b086', 'phui-header-view-css' => '083669db', 'phui-icon-view-css' => 'd35aa857', 'phui-image-mask-css' => '5a8b09c8', diff --git a/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php b/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php --- a/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php +++ b/src/applications/phortune/controller/PhortunePaymentMethodCreateController.php @@ -20,6 +20,7 @@ if (!$account) { return new Aphront404Response(); } + $account_id = $account->getID(); $merchant = id(new PhortuneMerchantQuery()) ->setViewer($viewer) @@ -30,8 +31,12 @@ } $cart_id = $request->getInt('cartID'); + $subscription_id = $request->getInt('subscriptionID'); if ($cart_id) { $cancel_uri = $this->getApplicationURI("cart/{$cart_id}/checkout/"); + } else if ($subscription_id) { + $cancel_uri = $this->getApplicationURI( + "{$account_id}/subscription/edit/{$subscription_id}/"); } else { $cancel_uri = $this->getApplicationURI($account->getID().'/'); } @@ -43,26 +48,31 @@ 'methods.'); } - $provider_id = $request->getInt('providerID'); - if (empty($providers[$provider_id])) { - $choices = array(); - foreach ($providers as $provider) { - $choices[] = $this->renderSelectProvider($provider); - } + if (count($providers) == 1) { + // If there's only one provider, always choose it. + $provider_id = head_key($providers); + } else { + $provider_id = $request->getInt('providerID'); + if (empty($providers[$provider_id])) { + $choices = array(); + foreach ($providers as $provider) { + $choices[] = $this->renderSelectProvider($provider); + } - $content = phutil_tag( - 'div', - array( - 'class' => 'phortune-payment-method-list', - ), - $choices); - - return $this->newDialog() - ->setRenderDialogAsDiv(true) - ->setTitle(pht('Add Payment Method')) - ->appendParagraph(pht('Choose a payment method to add:')) - ->appendChild($content) - ->addCancelButton($cancel_uri); + $content = phutil_tag( + 'div', + array( + 'class' => 'phortune-payment-method-list', + ), + $choices); + + return $this->newDialog() + ->setRenderDialogAsDiv(true) + ->setTitle(pht('Add Payment Method')) + ->appendParagraph(pht('Choose a payment method to add:')) + ->appendChild($content) + ->addCancelButton($cancel_uri); + } } $provider = $providers[$provider_id]; @@ -114,6 +124,8 @@ if ($cart_id) { $next_uri = $this->getApplicationURI( "cart/{$cart_id}/checkout/?paymentMethodID=".$method->getID()); + } else if ($subscription_id) { + $next_uri = $cancel_uri; } else { $account_uri = $this->getApplicationURI($account->getID().'/'); $next_uri = new PhutilURI($account_uri); @@ -140,6 +152,7 @@ ->setWorkflow(true) ->addHiddenInput('providerID', $provider_id) ->addHiddenInput('cartID', $request->getInt('cartID')) + ->addHiddenInput('subscriptionID', $request->getInt('subscriptionID')) ->addHiddenInput('isProviderForm', true) ->appendChild( id(new AphrontFormSubmitControl()) diff --git a/src/applications/phortune/controller/PhortuneSubscriptionEditController.php b/src/applications/phortune/controller/PhortuneSubscriptionEditController.php --- a/src/applications/phortune/controller/PhortuneSubscriptionEditController.php +++ b/src/applications/phortune/controller/PhortuneSubscriptionEditController.php @@ -103,6 +103,20 @@ $view_uri); $crumbs->addTextCrumb(pht('Edit')); + + $uri = $this->getApplicationURI($account->getID().'/card/new/'); + $uri = new PhutilURI($uri); + $uri->setQueryParam('merchantID', $merchant->getID()); + $uri->setQueryParam('subscriptionID', $subscription->getID()); + + $add_method_button = phutil_tag( + 'a', + array( + 'href' => $uri, + 'class' => 'button grey', + ), + pht('Add Payment Method...')); + $form = id(new AphrontFormView()) ->setUser($viewer) ->appendChild( @@ -112,6 +126,9 @@ ->setValue($current_phid) ->setOptions($options)) ->appendChild( + id(new AphrontFormMarkupControl()) + ->setValue($add_method_button)) + ->appendChild( id(new AphrontFormSubmitControl()) ->setValue(pht('Save Changes')) ->addCancelButton($view_uri)); diff --git a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php --- a/src/applications/phortune/provider/PhortuneStripePaymentProvider.php +++ b/src/applications/phortune/provider/PhortuneStripePaymentProvider.php @@ -277,6 +277,8 @@ array $errors) { $ccform = id(new PhortuneCreditCardForm()) + ->setSecurityAssurance( + pht('Payments are processed securely by Stripe.')) ->setUser($request->getUser()) ->setErrors($errors) ->addScript('https://js.stripe.com/v2/'); diff --git a/src/applications/phortune/provider/PhortuneTestPaymentProvider.php b/src/applications/phortune/provider/PhortuneTestPaymentProvider.php --- a/src/applications/phortune/provider/PhortuneTestPaymentProvider.php +++ b/src/applications/phortune/provider/PhortuneTestPaymentProvider.php @@ -144,6 +144,8 @@ array $errors) { $ccform = id(new PhortuneCreditCardForm()) + ->setSecurityAssurance( + pht('This is a test payment provider.')) ->setUser($request->getUser()) ->setErrors($errors); diff --git a/src/applications/phortune/view/PhortuneCreditCardForm.php b/src/applications/phortune/view/PhortuneCreditCardForm.php --- a/src/applications/phortune/view/PhortuneCreditCardForm.php +++ b/src/applications/phortune/view/PhortuneCreditCardForm.php @@ -10,6 +10,16 @@ private $cardNumberError; private $cardCVCError; private $cardExpirationError; + private $securityAssurance; + + public function setSecurityAssurance($security_assurance) { + $this->securityAssurance = $security_assurance; + return $this; + } + + public function getSecurityAssurance() { + return $this->securityAssurance; + } public function setUser(PhabricatorUser $user) { $this->user = $user; @@ -57,11 +67,11 @@ $errors = $this->errors; $e_number = isset($errors[PhortuneErrCode::ERR_CC_INVALID_NUMBER]) ? pht('Invalid') - : true; + : null; $e_cvc = isset($errors[PhortuneErrCode::ERR_CC_INVALID_CVC]) ? pht('Invalid') - : true; + : null; $e_expiry = isset($errors[PhortuneErrCode::ERR_CC_INVALID_EXPIRY]) ? pht('Invalid') @@ -70,37 +80,42 @@ $form ->setID($form_id) ->appendChild( - id(new AphrontFormMarkupControl()) - ->setLabel('') - ->setValue( - javelin_tag( - 'div', - array( - 'class' => 'credit-card-logos', - 'sigil' => 'has-tooltip', - 'meta' => array( - 'tip' => 'We support Visa, Mastercard, American Express, '. - 'Discover, JCB, and Diners Club.', - 'size' => 440, - ), - )))) - ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('Card Number') - ->setDisableAutocomplete(true) - ->setSigil('number-input') - ->setError($e_number)) + ->setLabel('Card Number') + ->setDisableAutocomplete(true) + ->setSigil('number-input') + ->setError($e_number)) ->appendChild( id(new AphrontFormTextControl()) - ->setLabel('CVC') - ->setDisableAutocomplete(true) - ->setSigil('cvc-input') - ->setError($e_cvc)) + ->setLabel('CVC') + ->setDisableAutocomplete(true) + ->addClass('aphront-form-cvc-input') + ->setSigil('cvc-input') + ->setError($e_cvc)) ->appendChild( id(new PhortuneMonthYearExpiryControl()) - ->setLabel('Expiration') - ->setUser($this->user) - ->setError($e_expiry)); + ->setLabel('Expiration') + ->setUser($this->user) + ->setError($e_expiry)); + + $assurance = $this->getSecurityAssurance(); + if ($assurance) { + $assurance = phutil_tag( + 'div', + array( + 'class' => 'phortune-security-assurance', + ), + array( + id(new PHUIIconView()) + ->setIconFont('fa-lock grey'), + ' ', + $assurance, + )); + + $form->appendChild( + id(new AphrontFormMarkupControl()) + ->setValue($assurance)); + } return $form; } diff --git a/src/view/form/control/AphrontFormControl.php b/src/view/form/control/AphrontFormControl.php --- a/src/view/form/control/AphrontFormControl.php +++ b/src/view/form/control/AphrontFormControl.php @@ -14,6 +14,7 @@ private $formPage; private $required; private $hidden; + private $classes; public function setHidden($hidden) { $this->hidden = $hidden; @@ -162,6 +163,11 @@ return true; } + public function addClass($class) { + $this->classes[] = $class; + return $this; + } + final public function render() { if (!$this->shouldRender()) { return null; @@ -225,6 +231,11 @@ $classes[] = 'aphront-form-control'; $classes[] = 'grouped'; $classes[] = $custom_class; + if ($this->classes) { + foreach ($this->classes as $class) { + $classes[] = $class; + } + } $style = $this->controlStyle; if ($this->hidden) { diff --git a/webroot/rsrc/css/application/phortune/phortune-credit-card-form.css b/webroot/rsrc/css/application/phortune/phortune-credit-card-form.css --- a/webroot/rsrc/css/application/phortune/phortune-credit-card-form.css +++ b/webroot/rsrc/css/application/phortune/phortune-credit-card-form.css @@ -2,7 +2,6 @@ * @provides phortune-credit-card-form-css */ -.credit-card-logos { - background: url(/rsrc/image/credit_cards.png) no-repeat 0px 2px; - height: 32px; +.phortune-security-assurance { + color: {$lightgreytext}; } diff --git a/webroot/rsrc/css/phui/phui-form-view.css b/webroot/rsrc/css/phui/phui-form-view.css --- a/webroot/rsrc/css/phui/phui-form-view.css +++ b/webroot/rsrc/css/phui/phui-form-view.css @@ -111,6 +111,10 @@ width: 100%; } +.aphront-form-cvc-input input { + width: 64px; +} + .aphront-form-input textarea { display: block; width: 100%; diff --git a/webroot/rsrc/image/credit_cards.png b/webroot/rsrc/image/credit_cards.png deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@