Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2895221
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
index 794f97aa8e..87bddd4d33 100644
--- a/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
+++ b/src/applications/phortune/controller/payment/PhortunePaymentMethodCreateController.php
@@ -1,279 +1,280 @@
<?php
final class PhortunePaymentMethodCreateController
extends PhortuneController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$account_id = $request->getURIData('accountID');
$account = id(new PhortuneAccountQuery())
->setViewer($viewer)
->withIDs(array($account_id))
->executeOne();
if (!$account) {
return new Aphront404Response();
}
$account_id = $account->getID();
$merchant = id(new PhortuneMerchantQuery())
->setViewer($viewer)
->withIDs(array($request->getInt('merchantID')))
->executeOne();
if (!$merchant) {
return new Aphront404Response();
}
$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().'/');
}
$providers = $this->loadCreatePaymentMethodProvidersForMerchant($merchant);
if (!$providers) {
throw new Exception(
pht(
'There are no payment providers enabled that can add payment '.
'methods.'));
}
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);
}
}
$provider = $providers[$provider_id];
$errors = array();
if ($request->isFormPost() && $request->getBool('isProviderForm')) {
$method = id(new PhortunePaymentMethod())
->setAccountPHID($account->getPHID())
->setAuthorPHID($viewer->getPHID())
->setMerchantPHID($merchant->getPHID())
->setProviderPHID($provider->getProviderConfig()->getPHID())
->setStatus(PhortunePaymentMethod::STATUS_ACTIVE);
if (!$errors) {
$errors = $this->processClientErrors(
$provider,
$request->getStr('errors'));
}
if (!$errors) {
$client_token_raw = $request->getStr('token');
$client_token = null;
try {
$client_token = phutil_json_decode($client_token_raw);
} catch (PhutilJSONParserException $ex) {
$errors[] = pht(
'There was an error decoding token information submitted by the '.
'client. Expected a JSON-encoded token dictionary, received: %s.',
nonempty($client_token_raw, pht('nothing')));
}
if (!$provider->validateCreatePaymentMethodToken($client_token)) {
$errors[] = pht(
'There was an error with the payment token submitted by the '.
'client. Expected a valid dictionary, received: %s.',
$client_token_raw);
}
if (!$errors) {
$errors = $provider->createPaymentMethodFromRequest(
$request,
$method,
$client_token);
}
}
if (!$errors) {
$method->save();
// If we added this method on a cart flow, return to the cart to
// check out.
if ($cart_id) {
$next_uri = $this->getApplicationURI(
"cart/{$cart_id}/checkout/?paymentMethodID=".$method->getID());
} else if ($subscription_id) {
- $next_uri = $cancel_uri;
+ $next_uri = new PhutilURI($cancel_uri);
+ $next_uri->setQueryParam('added', true);
} else {
$account_uri = $this->getApplicationURI($account->getID().'/');
$next_uri = new PhutilURI($account_uri);
$next_uri->setFragment('payment');
}
return id(new AphrontRedirectResponse())->setURI($next_uri);
} else {
$dialog = id(new AphrontDialogView())
->setUser($viewer)
->setTitle(pht('Error Adding Payment Method'))
->appendChild(id(new PHUIInfoView())->setErrors($errors))
->addCancelButton($request->getRequestURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
}
}
$form = $provider->renderCreatePaymentMethodForm($request, $errors);
$form
->setUser($viewer)
->setAction($request->getRequestURI())
->setWorkflow(true)
->addHiddenInput('providerID', $provider_id)
->addHiddenInput('cartID', $request->getInt('cartID'))
->addHiddenInput('subscriptionID', $request->getInt('subscriptionID'))
->addHiddenInput('isProviderForm', true)
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Add Payment Method'))
->addCancelButton($cancel_uri));
$box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Method'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Add Payment Method'));
$crumbs->setBorder(true);
$header = id(new PHUIHeaderView())
->setHeader(pht('Add Payment Method'))
->setHeaderIcon('fa-plus-square');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$box,
));
return $this->newPage()
->setTitle($provider->getPaymentMethodDescription())
->setCrumbs($crumbs)
->appendChild($view);
}
private function renderSelectProvider(
PhortunePaymentProvider $provider) {
$request = $this->getRequest();
$viewer = $request->getUser();
$description = $provider->getPaymentMethodDescription();
$icon_uri = $provider->getPaymentMethodIcon();
$details = $provider->getPaymentMethodProviderDescription();
$this->requireResource('phortune-css');
$icon = id(new PHUIIconView())
->setSpriteSheet(PHUIIconView::SPRITE_LOGIN)
->setSpriteIcon($provider->getPaymentMethodIcon());
$button = id(new PHUIButtonView())
->setSize(PHUIButtonView::BIG)
->setColor(PHUIButtonView::GREY)
->setIcon($icon)
->setText($description)
->setSubtext($details)
->setMetadata(array('disableWorkflow' => true));
$form = id(new AphrontFormView())
->setUser($viewer)
->setAction($request->getRequestURI())
->addHiddenInput('providerID', $provider->getProviderConfig()->getID())
->appendChild($button);
return $form;
}
private function processClientErrors(
PhortunePaymentProvider $provider,
$client_errors_raw) {
$errors = array();
$client_errors = null;
try {
$client_errors = phutil_json_decode($client_errors_raw);
} catch (PhutilJSONParserException $ex) {
$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;
}
}
diff --git a/src/applications/phortune/controller/payment/PhortunePaymentMethodDisableController.php b/src/applications/phortune/controller/payment/PhortunePaymentMethodDisableController.php
index d00db2725f..f5feec8a29 100644
--- a/src/applications/phortune/controller/payment/PhortunePaymentMethodDisableController.php
+++ b/src/applications/phortune/controller/payment/PhortunePaymentMethodDisableController.php
@@ -1,57 +1,58 @@
<?php
final class PhortunePaymentMethodDisableController
extends PhortuneController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$method_id = $request->getURIData('id');
$method = id(new PhortunePaymentMethodQuery())
->setViewer($viewer)
->withIDs(array($method_id))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$method) {
return new Aphront404Response();
}
if ($method->getStatus() == PhortunePaymentMethod::STATUS_DISABLED) {
return new Aphront400Response();
}
$account = $method->getAccount();
- $account_uri = $this->getApplicationURI($account->getID().'/');
+ $account_id = $account->getID();
+ $account_uri = $this->getApplicationURI("/account/billing/{$account_id}/");
if ($request->isFormPost()) {
- // TODO: ApplicationTransactions!
+ // TODO: ApplicationTransactions!!!!
$method
->setStatus(PhortunePaymentMethod::STATUS_DISABLED)
->save();
return id(new AphrontRedirectResponse())->setURI($account_uri);
}
return $this->newDialog()
->setTitle(pht('Remove Payment Method'))
->appendParagraph(
pht(
'Remove the payment method "%s" from your account?',
phutil_tag(
'strong',
array(),
$method->getFullDisplayName())))
->appendParagraph(
pht(
'You will no longer be able to make payments using this payment '.
'method.'))
->addCancelButton($account_uri)
->addSubmitButton(pht('Remove Payment Method'));
}
}
diff --git a/src/applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php b/src/applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php
index 185bbdbcc6..e7287f3d29 100644
--- a/src/applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php
+++ b/src/applications/phortune/controller/subscription/PhortuneSubscriptionEditController.php
@@ -1,172 +1,185 @@
<?php
final class PhortuneSubscriptionEditController extends PhortuneController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
+ $added = $request->getBool('added');
$subscription = id(new PhortuneSubscriptionQuery())
->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$subscription) {
return new Aphront404Response();
}
id(new PhabricatorAuthSessionEngine())->requireHighSecuritySession(
$viewer,
$request,
$subscription->getURI());
$merchant = $subscription->getMerchant();
$account = $subscription->getAccount();
$title = pht('Subscription: %s', $subscription->getSubscriptionName());
$header = id(new PHUIHeaderView())
->setHeader($subscription->getSubscriptionName());
$view_uri = $subscription->getURI();
$valid_methods = id(new PhortunePaymentMethodQuery())
->setViewer($viewer)
->withAccountPHIDs(array($account->getPHID()))
->withStatuses(
array(
PhortunePaymentMethod::STATUS_ACTIVE,
))
->withMerchantPHIDs(array($merchant->getPHID()))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$valid_methods = mpull($valid_methods, null, 'getPHID');
$current_phid = $subscription->getDefaultPaymentMethodPHID();
$e_method = null;
if ($current_phid && empty($valid_methods[$current_phid])) {
$e_method = pht('Needs Update');
}
$errors = array();
if ($request->isFormPost()) {
$default_method_phid = $request->getStr('defaultPaymentMethodPHID');
if (!$default_method_phid) {
$default_method_phid = null;
$e_method = null;
} else if (empty($valid_methods[$default_method_phid])) {
$e_method = pht('Invalid');
if ($default_method_phid == $current_phid) {
$errors[] = pht(
'This subscription is configured to autopay with a payment method '.
'that has been deleted. Choose a valid payment method or disable '.
'autopay.');
} else {
$errors[] = pht('You must select a valid default payment method.');
}
}
// TODO: We should use transactions here, and move the validation logic
// inside the Editor.
if (!$errors) {
$subscription->setDefaultPaymentMethodPHID($default_method_phid);
$subscription->save();
return id(new AphrontRedirectResponse())
->setURI($view_uri);
}
}
// Add the option to disable autopay.
$disable_options = array(
'' => pht('(Disable Autopay)'),
);
// Don't require the user to make a valid selection if the current method
// has become invalid.
if ($current_phid && empty($valid_methods[$current_phid])) {
$current_options = array(
$current_phid => pht('<Deleted Payment Method>'),
);
} else {
$current_options = array();
}
// Add any available options.
$valid_options = mpull($valid_methods, 'getFullDisplayName', 'getPHID');
$options = $disable_options + $current_options + $valid_options;
$crumbs = $this->buildApplicationCrumbs();
$this->addAccountCrumb($crumbs, $account);
$crumbs->addTextCrumb(
pht('Subscription %d', $subscription->getID()),
$view_uri);
$crumbs->addTextCrumb(pht('Edit'));
+ $crumbs->setBorder(true);
$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 button-grey',
),
pht('Add Payment Method...'));
+ $radio = id(new AphrontFormRadioButtonControl())
+ ->setName('defaultPaymentMethodPHID')
+ ->setLabel(pht('Autopay With'))
+ ->setValue($current_phid)
+ ->setError($e_method);
+
+ foreach ($options as $key => $value) {
+ $radio->addButton($key, $value, null);
+ }
+
$form = id(new AphrontFormView())
->setUser($viewer)
- ->appendChild(
- id(new AphrontFormSelectControl())
- ->setName('defaultPaymentMethodPHID')
- ->setLabel(pht('Autopay With'))
- ->setValue($current_phid)
- ->setError($e_method)
- ->setOptions($options))
+ ->appendChild($radio)
->appendChild(
id(new AphrontFormMarkupControl())
->setValue($add_method_button))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save Changes'))
->addCancelButton($view_uri));
$box = id(new PHUIObjectBoxView())
->setUser($viewer)
->setHeaderText(pht('Subscription'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setFormErrors($errors)
->appendChild($form);
+ if ($added) {
+ $info_view = id(new PHUIInfoView())
+ ->setSeverity(PHUIInfoView::SEVERITY_SUCCESS)
+ ->appendChild(pht('Payment method has been successfully added.'));
+ $box->setInfoView($info_view);
+ }
+
$header = id(new PHUIHeaderView())
->setHeader(pht('Edit %s', $subscription->getSubscriptionName()))
->setHeaderIcon('fa-pencil');
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter(array(
$box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Jan 19 2025, 21:07 (6 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1128765
Default Alt Text
(18 KB)
Attached To
Mode
rP Phorge
Attached
Detach File
Event Timeline
Log In to Comment