Page MenuHomePhabricator

D10644.id.diff
No OneTemporary

D10644.id.diff

diff --git a/src/applications/phortune/controller/PhortuneProviderController.php b/src/applications/phortune/controller/PhortuneProviderController.php
--- a/src/applications/phortune/controller/PhortuneProviderController.php
+++ b/src/applications/phortune/controller/PhortuneProviderController.php
@@ -71,4 +71,18 @@
->executeOne();
}
+ public function loadActiveCharge(PhortuneCart $cart) {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+
+ return id(new PhortuneChargeQuery())
+ ->setViewer($viewer)
+ ->withCartPHIDs(array($cart->getPHID()))
+ ->withStatuses(
+ array(
+ PhortuneCharge::STATUS_CHARGING,
+ ))
+ ->executeOne();
+ }
+
}
diff --git a/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php b/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php
--- a/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php
+++ b/src/applications/phortune/provider/PhortunePaypalPaymentProvider.php
@@ -3,6 +3,9 @@
final class PhortunePaypalPaymentProvider extends PhortunePaymentProvider {
public function isEnabled() {
+ // TODO: See note in processControllerRequest().
+ return false;
+
return $this->getPaypalAPIUsername() &&
$this->getPaypalAPIPassword() &&
$this->getPaypalAPISignature();
@@ -74,11 +77,28 @@
PhortuneProviderController $controller,
AphrontRequest $request) {
+ $viewer = $request->getUser();
+
$cart = $controller->loadCart($request->getInt('cartID'));
if (!$cart) {
return new Aphront404Response();
}
+ $charge = $controller->loadActiveCharge($cart);
+ switch ($controller->getAction()) {
+ case 'checkout':
+ if ($charge) {
+ throw new Exception(pht('Cart is already charging!'));
+ }
+ break;
+ case 'charge':
+ case 'cancel':
+ if (!$charge) {
+ throw new Exception(pht('Cart is not charging yet!'));
+ }
+ break;
+ }
+
switch ($controller->getAction()) {
case 'checkout':
$return_uri = $this->getControllerURI(
@@ -95,17 +115,25 @@
$price = $cart->getTotalPriceAsCurrency();
+ $charge = $cart->willApplyCharge($viewer, $this);
+
+ $params = array(
+ 'PAYMENTREQUEST_0_AMT' => $price->formatBareValue(),
+ 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(),
+ 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
+ 'PAYMENTREQUEST_0_CUSTOM' => $charge->getPHID(),
+
+ 'RETURNURL' => $return_uri,
+ 'CANCELURL' => $cancel_uri,
+
+ // TODO: This should be cart-dependent if we eventually support
+ // physical goods.
+ 'NOSHIPPING' => '1',
+ );
+
$result = $this
->newPaypalAPICall()
- ->setRawPayPalQuery(
- 'SetExpressCheckout',
- array(
- 'PAYMENTREQUEST_0_AMT' => $price->formatBareValue(),
- 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(),
- 'RETURNURL' => $return_uri,
- 'CANCELURL' => $cancel_uri,
- 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
- ))
+ ->setRawPayPalQuery('SetExpressCheckout', $params)
->resolve();
$uri = new PhutilURI('https://www.sandbox.paypal.com/cgi-bin/webscr');
@@ -115,18 +143,74 @@
'token' => $result['TOKEN'],
));
+ $cart->setMetadataValue('provider.checkoutURI', $uri);
+ $cart->save();
+
+ $charge->setMetadataValue('paypal.token', $result['TOKEN']);
+ $charge->save();
+
return id(new AphrontRedirectResponse())
->setIsExternal(true)
->setURI($uri);
case 'charge':
- var_dump($_REQUEST);
+ $token = $request->getStr('token');
+
+ $params = array(
+ 'TOKEN' => $token,
+ );
+
+ $result = $this
+ ->newPaypalAPICall()
+ ->setRawPayPalQuery('GetExpressCheckoutDetails', $params)
+ ->resolve();
+
+ var_dump($result);
+
+ if ($result['CUSTOM'] !== $charge->getPHID()) {
+ throw new Exception(
+ pht('Paypal checkout does not match Phortune charge!'));
+ }
+
+ if ($result['CHECKOUTSTATUS'] !== 'PaymentActionNotInitiated') {
+ throw new Exception(
+ pht(
+ 'Expected status "%s", got "%s".',
+ 'PaymentActionNotInitiated',
+ $result['CHECKOUTSTATUS']));
+ }
+
+ $price = $cart->getTotalPriceAsCurrency();
+
+ $params = array(
+ 'TOKEN' => $token,
+ 'PAYERID' => $result['PAYERID'],
+
+ 'PAYMENTREQUEST_0_AMT' => $price->formatBareValue(),
+ 'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(),
+ 'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
+ );
+
+ $result = $this
+ ->newPaypalAPICall()
+ ->setRawPayPalQuery('DoExpressCheckoutPayment', $params)
+ ->resolve();
+
+ // TODO: Paypal can send requests back in "PaymentReview" status,
+ // and does this for test transactions. We're supposed to hold
+ // the transaction and poll the API every 6 hours. This is unreasonably
+ // difficult for now and we can't reasonably just fail these charges.
+
+ var_dump($result);
+
+ die();
break;
case 'cancel':
var_dump($_REQUEST);
break;
}
- throw new Exception("The rest of this isn't implemented yet.");
+ throw new Exception(
+ pht('Unsupported action "%s".', $controller->getAction()));
}
private function newPaypalAPICall() {
diff --git a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
--- a/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
+++ b/src/applications/phortune/provider/PhortuneWePayPaymentProvider.php
@@ -100,15 +100,7 @@
$wepay = new WePay($this->getWePayAccessToken());
- $charge = id(new PhortuneChargeQuery())
- ->setViewer($viewer)
- ->withCartPHIDs(array($cart->getPHID()))
- ->withStatuses(
- array(
- PhortuneCharge::STATUS_CHARGING,
- ))
- ->executeOne();
-
+ $charge = $controller->loadActiveCharge($cart);
switch ($controller->getAction()) {
case 'checkout':
if ($charge) {

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 20, 7:46 PM (3 w, 22 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7388639
Default Alt Text
D10644.id.diff (6 KB)

Event Timeline