Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15311997
D11935.id28749.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Referenced Files
None
Subscribers
None
D11935.id28749.diff
View Options
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 dc54a4fca4f4fed984c52481e798c759da9d2d75..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001
literal 5963
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
aDOsW{q5t~@>K{bwisNZ-gNFWJ8~+36`E8^C
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mar 7 2025, 12:52 PM (6 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7332621
Default Alt Text
D11935.id28749.diff (18 KB)
Attached To
Mode
D11935: Make it easier to add payment methods for subscription autopay
Attached
Detach File
Event Timeline
Log In to Comment