mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-04 12:42:43 +01:00
Implement Phortune charge updates
Summary: Ref T2787. These don't necessarily do a ton yet, but we can get PayPal out of hold, at least. Test Plan: Updated charges from all providers. Cleared a PayPal hold. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D10670
This commit is contained in:
parent
2a2fb62229
commit
f41ae2228a
12 changed files with 214 additions and 68 deletions
|
@ -79,6 +79,8 @@ final class FundBackerProduct extends PhortuneProductImplementation {
|
||||||
public function didPurchaseProduct(
|
public function didPurchaseProduct(
|
||||||
PhortuneProduct $product,
|
PhortuneProduct $product,
|
||||||
PhortunePurchase $purchase) {
|
PhortunePurchase $purchase) {
|
||||||
|
// TODO: This viewer may be wrong if the purchase completes after a hold
|
||||||
|
// we should load the backer explicitly.
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
$backer = id(new FundBackerQuery())
|
$backer = id(new FundBackerQuery())
|
||||||
|
|
|
@ -169,6 +169,8 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
->withStatuses(
|
->withStatuses(
|
||||||
array(
|
array(
|
||||||
PhortuneCart::STATUS_PURCHASING,
|
PhortuneCart::STATUS_PURCHASING,
|
||||||
|
PhortuneCart::STATUS_CHARGED,
|
||||||
|
PhortuneCart::STATUS_HOLD,
|
||||||
PhortuneCart::STATUS_PURCHASED,
|
PhortuneCart::STATUS_PURCHASED,
|
||||||
))
|
))
|
||||||
->execute();
|
->execute();
|
||||||
|
@ -197,6 +199,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
|
|
||||||
$rowc[] = '';
|
$rowc[] = '';
|
||||||
$rows[] = array(
|
$rows[] = array(
|
||||||
|
$cart->getID(),
|
||||||
phutil_tag(
|
phutil_tag(
|
||||||
'strong',
|
'strong',
|
||||||
array(),
|
array(),
|
||||||
|
@ -206,6 +209,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
'strong',
|
'strong',
|
||||||
array(),
|
array(),
|
||||||
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
|
$cart->getTotalPriceAsCurrency()->formatForDisplay()),
|
||||||
|
PhortuneCart::getNameForStatus($cart->getStatus()),
|
||||||
phabricator_datetime($cart->getDateModified(), $viewer),
|
phabricator_datetime($cart->getDateModified(), $viewer),
|
||||||
);
|
);
|
||||||
foreach ($purchases as $purchase) {
|
foreach ($purchases as $purchase) {
|
||||||
|
@ -219,6 +223,7 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
$handles[$purchase->getPHID()]->renderLink(),
|
$handles[$purchase->getPHID()]->renderLink(),
|
||||||
$price,
|
$price,
|
||||||
'',
|
'',
|
||||||
|
'',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,21 +232,25 @@ final class PhortuneAccountViewController extends PhortuneController {
|
||||||
->setRowClasses($rowc)
|
->setRowClasses($rowc)
|
||||||
->setHeaders(
|
->setHeaders(
|
||||||
array(
|
array(
|
||||||
pht('Cart'),
|
pht('ID'),
|
||||||
|
pht('Order'),
|
||||||
pht('Purchase'),
|
pht('Purchase'),
|
||||||
pht('Amount'),
|
pht('Amount'),
|
||||||
|
pht('Status'),
|
||||||
pht('Updated'),
|
pht('Updated'),
|
||||||
))
|
))
|
||||||
->setColumnClasses(
|
->setColumnClasses(
|
||||||
array(
|
array(
|
||||||
|
'',
|
||||||
'',
|
'',
|
||||||
'wide',
|
'wide',
|
||||||
'right',
|
'right',
|
||||||
|
'',
|
||||||
'right',
|
'right',
|
||||||
));
|
));
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setHeader(pht('Purchase History'));
|
->setHeader(pht('Order History'));
|
||||||
|
|
||||||
return id(new PHUIObjectBoxView())
|
return id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
|
|
@ -22,7 +22,41 @@ final class PhortuneCartUpdateController
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This obviously doesn't do anything for now.
|
$charges = id(new PhortuneChargeQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withCartPHIDs(array($cart->getPHID()))
|
||||||
|
->needCarts(true)
|
||||||
|
->withStatuses(
|
||||||
|
array(
|
||||||
|
PhortuneCharge::STATUS_HOLD,
|
||||||
|
PhortuneCharge::STATUS_CHARGED,
|
||||||
|
))
|
||||||
|
->execute();
|
||||||
|
|
||||||
|
if ($charges) {
|
||||||
|
$providers = id(new PhortunePaymentProviderConfigQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(mpull($charges, 'getProviderPHID'))
|
||||||
|
->execute();
|
||||||
|
$providers = mpull($providers, null, 'getPHID');
|
||||||
|
} else {
|
||||||
|
$providers = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($charges as $charge) {
|
||||||
|
if ($charge->isRefund()) {
|
||||||
|
// Don't update refunds.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$provider_config = idx($providers, $charge->getProviderPHID());
|
||||||
|
if (!$provider_config) {
|
||||||
|
throw new Exception(pht('Unable to load provider for charge!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$provider = $provider_config->buildProvider();
|
||||||
|
$provider->updateCharge($charge);
|
||||||
|
}
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())
|
return id(new AphrontRedirectResponse())
|
||||||
->setURI($cart->getDetailURI());
|
->setURI($cart->getDetailURI());
|
||||||
|
|
|
@ -83,8 +83,7 @@ final class PhortuneCartViewController
|
||||||
|
|
||||||
$header = id(new PHUIHeaderView())
|
$header = id(new PHUIHeaderView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setHeader(pht('Order Detail'))
|
->setHeader(pht('Order Detail'));
|
||||||
->setPolicyObject($cart);
|
|
||||||
|
|
||||||
$cart_box = id(new PHUIObjectBoxView())
|
$cart_box = id(new PHUIObjectBoxView())
|
||||||
->setHeader($header)
|
->setHeader($header)
|
||||||
|
|
|
@ -102,10 +102,7 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runConfigurationTest() {
|
public function runConfigurationTest() {
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$this->loadBalancedAPILibraries();
|
||||||
require_once $root.'/externals/httpful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/restful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/balanced-php/bootstrap.php';
|
|
||||||
|
|
||||||
// TODO: This only tests that the secret key is correct. It's not clear
|
// TODO: This only tests that the secret key is correct. It's not clear
|
||||||
// how to test that the marketplace is correct.
|
// how to test that the marketplace is correct.
|
||||||
|
@ -140,11 +137,7 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
protected function executeCharge(
|
protected function executeCharge(
|
||||||
PhortunePaymentMethod $method,
|
PhortunePaymentMethod $method,
|
||||||
PhortuneCharge $charge) {
|
PhortuneCharge $charge) {
|
||||||
|
$this->loadBalancedAPILibraries();
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/httpful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/restful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/balanced-php/bootstrap.php';
|
|
||||||
|
|
||||||
$price = $charge->getAmountAsCurrency();
|
$price = $charge->getAmountAsCurrency();
|
||||||
|
|
||||||
|
@ -182,11 +175,7 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
protected function executeRefund(
|
protected function executeRefund(
|
||||||
PhortuneCharge $charge,
|
PhortuneCharge $charge,
|
||||||
PhortuneCharge $refund) {
|
PhortuneCharge $refund) {
|
||||||
|
$this->loadBalancedAPILibraries();
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/httpful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/restful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/balanced-php/bootstrap.php';
|
|
||||||
|
|
||||||
$debit_uri = $charge->getMetadataValue('balanced.debitURI');
|
$debit_uri = $charge->getMetadataValue('balanced.debitURI');
|
||||||
if (!$debit_uri) {
|
if (!$debit_uri) {
|
||||||
|
@ -214,6 +203,24 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
$refund->save();
|
$refund->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCharge(PhortuneCharge $charge) {
|
||||||
|
$this->loadBalancedAPILibraries();
|
||||||
|
|
||||||
|
$debit_uri = $charge->getMetadataValue('balanced.debitURI');
|
||||||
|
if (!$debit_uri) {
|
||||||
|
throw new Exception(pht('No Balanced debit URI!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Balanced\Settings::$api_key = $this->getSecretKey();
|
||||||
|
$balanced_debit = Balanced\Debit::get($debit_uri);
|
||||||
|
} catch (RESTful\Exceptions\HTTPError $error) {
|
||||||
|
throw new Exception($error->response->body->description);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Deal with disputes / chargebacks / surprising refunds.
|
||||||
|
}
|
||||||
|
|
||||||
private function getMarketplaceID() {
|
private function getMarketplaceID() {
|
||||||
return $this
|
return $this
|
||||||
->getProviderConfig()
|
->getProviderConfig()
|
||||||
|
@ -255,14 +262,10 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
AphrontRequest $request,
|
AphrontRequest $request,
|
||||||
PhortunePaymentMethod $method,
|
PhortunePaymentMethod $method,
|
||||||
array $token) {
|
array $token) {
|
||||||
|
$this->loadBalancedAPILibraries();
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/httpful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/restful/bootstrap.php';
|
|
||||||
require_once $root.'/externals/balanced-php/bootstrap.php';
|
|
||||||
|
|
||||||
$account_phid = $method->getAccountPHID();
|
$account_phid = $method->getAccountPHID();
|
||||||
$author_phid = $method->getAuthorPHID();
|
$author_phid = $method->getAuthorPHID();
|
||||||
$description = $account_phid.':'.$author_phid;
|
$description = $account_phid.':'.$author_phid;
|
||||||
|
@ -357,4 +360,11 @@ final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loadBalancedAPILibraries() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
require_once $root.'/externals/httpful/bootstrap.php';
|
||||||
|
require_once $root.'/externals/restful/bootstrap.php';
|
||||||
|
require_once $root.'/externals/balanced-php/bootstrap.php';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,62 @@ final class PhortunePayPalPaymentProvider extends PhortunePaymentProvider {
|
||||||
$result['REFUNDTRANSACTIONID']);
|
$result['REFUNDTRANSACTIONID']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCharge(PhortuneCharge $charge) {
|
||||||
|
$transaction_id = $charge->getMetadataValue('paypal.transactionID');
|
||||||
|
if (!$transaction_id) {
|
||||||
|
throw new Exception(pht('Charge has no transaction ID!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'TRANSACTIONID' => $transaction_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this
|
||||||
|
->newPaypalAPICall()
|
||||||
|
->setRawPayPalQuery('GetTransactionDetails', $params)
|
||||||
|
->resolve();
|
||||||
|
|
||||||
|
$is_charge = false;
|
||||||
|
$is_fail = false;
|
||||||
|
switch ($result['PAYMENTSTATUS']) {
|
||||||
|
case 'Processed':
|
||||||
|
case 'Completed':
|
||||||
|
case 'Completed-Funds-Held':
|
||||||
|
$is_charge = true;
|
||||||
|
break;
|
||||||
|
case 'Partially-Refunded':
|
||||||
|
case 'Refunded':
|
||||||
|
case 'Reversed':
|
||||||
|
case 'Canceled-Reversal':
|
||||||
|
// TODO: Handle these.
|
||||||
|
return;
|
||||||
|
case 'In-Progress':
|
||||||
|
case 'Pending':
|
||||||
|
// TODO: Also handle these better?
|
||||||
|
return;
|
||||||
|
case 'Denied':
|
||||||
|
case 'Expired':
|
||||||
|
case 'Failed':
|
||||||
|
case 'None':
|
||||||
|
case 'Voided':
|
||||||
|
default:
|
||||||
|
$is_fail = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($charge->getStatus() == PhortuneCharge::STATUS_HOLD) {
|
||||||
|
$cart = $charge->getCart();
|
||||||
|
|
||||||
|
$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||||
|
if ($is_charge) {
|
||||||
|
$cart->didApplyCharge($charge);
|
||||||
|
} else if ($is_fail) {
|
||||||
|
$cart->didFailCharge($charge);
|
||||||
|
}
|
||||||
|
unset($unguarded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function getPaypalAPIUsername() {
|
private function getPaypalAPIUsername() {
|
||||||
return $this
|
return $this
|
||||||
->getProviderConfig()
|
->getProviderConfig()
|
||||||
|
@ -278,6 +334,7 @@ final class PhortunePayPalPaymentProvider extends PhortunePaymentProvider {
|
||||||
'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(),
|
'PAYMENTREQUEST_0_CURRENCYCODE' => $price->getCurrency(),
|
||||||
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
|
'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
|
||||||
'PAYMENTREQUEST_0_CUSTOM' => $charge->getPHID(),
|
'PAYMENTREQUEST_0_CUSTOM' => $charge->getPHID(),
|
||||||
|
'PAYMENTREQUEST_0_DESC' => $cart->getName(),
|
||||||
|
|
||||||
'RETURNURL' => $return_uri,
|
'RETURNURL' => $return_uri,
|
||||||
'CANCELURL' => $cancel_uri,
|
'CANCELURL' => $cancel_uri,
|
||||||
|
|
|
@ -149,7 +149,9 @@ abstract class PhortunePaymentProvider {
|
||||||
|
|
||||||
abstract protected function executeRefund(
|
abstract protected function executeRefund(
|
||||||
PhortuneCharge $charge,
|
PhortuneCharge $charge,
|
||||||
PhortuneCharge $charge);
|
PhortuneCharge $refund);
|
||||||
|
|
||||||
|
abstract public function updateCharge(PhortuneCharge $charge);
|
||||||
|
|
||||||
|
|
||||||
/* -( Adding Payment Methods )--------------------------------------------- */
|
/* -( Adding Payment Methods )--------------------------------------------- */
|
||||||
|
|
|
@ -116,8 +116,7 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runConfigurationTest() {
|
public function runConfigurationTest() {
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$this->loadStripeAPILibraries();
|
||||||
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
|
||||||
|
|
||||||
$secret_key = $this->getSecretKey();
|
$secret_key = $this->getSecretKey();
|
||||||
$account = Stripe_Account::retrieve($secret_key);
|
$account = Stripe_Account::retrieve($secret_key);
|
||||||
|
@ -131,9 +130,7 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
protected function executeCharge(
|
protected function executeCharge(
|
||||||
PhortunePaymentMethod $method,
|
PhortunePaymentMethod $method,
|
||||||
PhortuneCharge $charge) {
|
PhortuneCharge $charge) {
|
||||||
|
$this->loadStripeAPILibraries();
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
|
||||||
|
|
||||||
$price = $charge->getAmountAsCurrency();
|
$price = $charge->getAmountAsCurrency();
|
||||||
|
|
||||||
|
@ -160,6 +157,7 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
protected function executeRefund(
|
protected function executeRefund(
|
||||||
PhortuneCharge $charge,
|
PhortuneCharge $charge,
|
||||||
PhortuneCharge $refund) {
|
PhortuneCharge $refund) {
|
||||||
|
$this->loadStripeAPILibraries();
|
||||||
|
|
||||||
$charge_id = $charge->getMetadataValue('stripe.chargeID');
|
$charge_id = $charge->getMetadataValue('stripe.chargeID');
|
||||||
if (!$charge_id) {
|
if (!$charge_id) {
|
||||||
|
@ -167,9 +165,6 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
pht('Unable to refund charge; no Stripe chargeID!'));
|
pht('Unable to refund charge; no Stripe chargeID!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
|
||||||
|
|
||||||
$refund_cents = $refund
|
$refund_cents = $refund
|
||||||
->getAmountAsCurrency()
|
->getAmountAsCurrency()
|
||||||
->negate()
|
->negate()
|
||||||
|
@ -192,6 +187,22 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
$charge->save();
|
$charge->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCharge(PhortuneCharge $charge) {
|
||||||
|
$this->loadStripeAPILibraries();
|
||||||
|
|
||||||
|
$charge_id = $charge->getMetadataValue('stripe.chargeID');
|
||||||
|
if (!$charge_id) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('Unable to update charge; no Stripe chargeID!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$secret_key = $this->getSecretKey();
|
||||||
|
$stripe_charge = Stripe_Charge::retrieve($charge_id, $secret_key);
|
||||||
|
|
||||||
|
// TODO: Deal with disputes / chargebacks / surprising refunds.
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private function getPublishableKey() {
|
private function getPublishableKey() {
|
||||||
return $this
|
return $this
|
||||||
->getProviderConfig()
|
->getProviderConfig()
|
||||||
|
@ -221,12 +232,10 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
AphrontRequest $request,
|
AphrontRequest $request,
|
||||||
PhortunePaymentMethod $method,
|
PhortunePaymentMethod $method,
|
||||||
array $token) {
|
array $token) {
|
||||||
|
$this->loadStripeAPILibraries();
|
||||||
|
|
||||||
$errors = array();
|
$errors = array();
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
|
||||||
|
|
||||||
$secret_key = $this->getSecretKey();
|
$secret_key = $this->getSecretKey();
|
||||||
$stripe_token = $token['stripeCardToken'];
|
$stripe_token = $token['stripeCardToken'];
|
||||||
|
|
||||||
|
@ -362,4 +371,9 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loadStripeAPILibraries() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
require_once $root.'/externals/stripe-php/lib/Stripe.php';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,10 @@ final class PhortuneTestPaymentProvider extends PhortunePaymentProvider {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCharge(PhortuneCharge $charge) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllConfigurableProperties() {
|
public function getAllConfigurableProperties() {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,7 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runConfigurationTest() {
|
public function runConfigurationTest() {
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$this->loadWePayAPILibraries();
|
||||||
require_once $root.'/externals/wepay/wepay.php';
|
|
||||||
|
|
||||||
WePay::useStaging(
|
WePay::useStaging(
|
||||||
$this->getWePayClientID(),
|
$this->getWePayClientID(),
|
||||||
|
@ -189,20 +188,12 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
protected function executeRefund(
|
protected function executeRefund(
|
||||||
PhortuneCharge $charge,
|
PhortuneCharge $charge,
|
||||||
PhortuneCharge $refund) {
|
PhortuneCharge $refund) {
|
||||||
|
$wepay = $this->loadWePayAPILibraries();
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$checkout_id = $this->getWePayCheckoutID($charge);
|
||||||
require_once $root.'/externals/wepay/wepay.php';
|
|
||||||
|
|
||||||
WePay::useStaging(
|
|
||||||
$this->getWePayClientID(),
|
|
||||||
$this->getWePayClientSecret());
|
|
||||||
|
|
||||||
$wepay = new WePay($this->getWePayAccessToken());
|
|
||||||
|
|
||||||
$charge_id = $charge->getMetadataValue('wepay.checkoutID');
|
|
||||||
|
|
||||||
$params = array(
|
$params = array(
|
||||||
'checkout_id' => $charge_id,
|
'checkout_id' => $checkout_id,
|
||||||
'refund_reason' => pht('Refund'),
|
'refund_reason' => pht('Refund'),
|
||||||
'amount' => $refund->getAmountAsCurrency()->negate()->formatBareValue(),
|
'amount' => $refund->getAmountAsCurrency()->negate()->formatBareValue(),
|
||||||
);
|
);
|
||||||
|
@ -210,6 +201,18 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
$wepay->request('checkout/refund', $params);
|
$wepay->request('checkout/refund', $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateCharge(PhortuneCharge $charge) {
|
||||||
|
$wepay = $this->loadWePayAPILibraries();
|
||||||
|
|
||||||
|
$params = array(
|
||||||
|
'checkout_id' => $this->getWePayCheckoutID($charge),
|
||||||
|
);
|
||||||
|
$wepay_checkout = $wepay->request('checkout', $params);
|
||||||
|
|
||||||
|
// TODO: Deal with disputes / chargebacks / surprising refunds.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -( One-Time Payments )-------------------------------------------------- */
|
/* -( One-Time Payments )-------------------------------------------------- */
|
||||||
|
|
||||||
public function canProcessOneTimePayments() {
|
public function canProcessOneTimePayments() {
|
||||||
|
@ -236,6 +239,7 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
public function processControllerRequest(
|
public function processControllerRequest(
|
||||||
PhortuneProviderActionController $controller,
|
PhortuneProviderActionController $controller,
|
||||||
AphrontRequest $request) {
|
AphrontRequest $request) {
|
||||||
|
$wepay = $this->loadWePayAPILibraries();
|
||||||
|
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
@ -244,15 +248,6 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
|
||||||
require_once $root.'/externals/wepay/wepay.php';
|
|
||||||
|
|
||||||
WePay::useStaging(
|
|
||||||
$this->getWePayClientID(),
|
|
||||||
$this->getWePayClientSecret());
|
|
||||||
|
|
||||||
$wepay = new WePay($this->getWePayAccessToken());
|
|
||||||
|
|
||||||
$charge = $controller->loadActiveCharge($cart);
|
$charge = $controller->loadActiveCharge($cart);
|
||||||
switch ($controller->getAction()) {
|
switch ($controller->getAction()) {
|
||||||
case 'checkout':
|
case 'checkout':
|
||||||
|
@ -388,5 +383,23 @@ final class PhortuneWePayPaymentProvider extends PhortunePaymentProvider {
|
||||||
pht('Unsupported action "%s".', $controller->getAction()));
|
pht('Unsupported action "%s".', $controller->getAction()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function loadWePayAPILibraries() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
require_once $root.'/externals/wepay/wepay.php';
|
||||||
|
|
||||||
|
WePay::useStaging(
|
||||||
|
$this->getWePayClientID(),
|
||||||
|
$this->getWePayClientSecret());
|
||||||
|
|
||||||
|
return new WePay($this->getWePayAccessToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getWePayCheckoutID(PhortuneCharge $charge) {
|
||||||
|
$checkout_id = $charge->getMetadataValue('wepay.checkoutID');
|
||||||
|
if ($checkout_id === null) {
|
||||||
|
throw new Exception(pht('No WePay Checkout ID present on charge!'));
|
||||||
|
}
|
||||||
|
return $checkout_id;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,13 +149,12 @@ final class PhortuneCart extends PhortuneDAO
|
||||||
$copy = clone $this;
|
$copy = clone $this;
|
||||||
$copy->reload();
|
$copy->reload();
|
||||||
|
|
||||||
if ($copy->getStatus() !== self::STATUS_PURCHASING) {
|
if (($copy->getStatus() !== self::STATUS_PURCHASING) &&
|
||||||
|
($copy->getStatus() !== self::STATUS_HOLD)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'Cart has wrong status ("%s") to call didApplyCharge(), '.
|
'Cart has wrong status ("%s") to call didApplyCharge().',
|
||||||
'expected "%s".',
|
$copy->getStatus()));
|
||||||
$copy->getStatus(),
|
|
||||||
self::STATUS_PURCHASING));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$charge->save();
|
$charge->save();
|
||||||
|
@ -182,13 +181,12 @@ final class PhortuneCart extends PhortuneDAO
|
||||||
$copy = clone $this;
|
$copy = clone $this;
|
||||||
$copy->reload();
|
$copy->reload();
|
||||||
|
|
||||||
if ($copy->getStatus() !== self::STATUS_PURCHASING) {
|
if (($copy->getStatus() !== self::STATUS_PURCHASING) &&
|
||||||
|
($copy->getStatus() !== self::STATUS_HOLD)) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
pht(
|
pht(
|
||||||
'Cart has wrong status ("%s") to call didFailCharge(), '.
|
'Cart has wrong status ("%s") to call didFailCharge().',
|
||||||
'expected "%s".',
|
$copy->getStatus()));
|
||||||
$copy->getStatus(),
|
|
||||||
self::STATUS_PURCHASING));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$charge->save();
|
$charge->save();
|
||||||
|
|
|
@ -84,6 +84,10 @@ final class PhortuneCharge extends PhortuneDAO
|
||||||
return idx(self::getStatusNameMap(), $status, pht('Unknown'));
|
return idx(self::getStatusNameMap(), $status, pht('Unknown'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isRefund() {
|
||||||
|
return $this->getAmountAsCurrency()->negate()->isPositive();
|
||||||
|
}
|
||||||
|
|
||||||
public function getStatusForDisplay() {
|
public function getStatusForDisplay() {
|
||||||
if ($this->getStatus() == self::STATUS_CHARGED) {
|
if ($this->getStatus() == self::STATUS_CHARGED) {
|
||||||
if ($this->getRefundedChargePHID()) {
|
if ($this->getRefundedChargePHID()) {
|
||||||
|
|
Loading…
Reference in a new issue