2013-04-25 18:45:43 +02:00
|
|
|
<?php
|
|
|
|
|
2013-04-25 18:46:32 +02:00
|
|
|
/**
|
|
|
|
* @task addmethod Adding Payment Methods
|
|
|
|
*/
|
2013-04-25 18:45:43 +02:00
|
|
|
abstract class PhortunePaymentProvider {
|
|
|
|
|
2013-04-25 18:46:32 +02:00
|
|
|
|
|
|
|
/* -( Selecting Providers )------------------------------------------------ */
|
|
|
|
|
|
|
|
|
|
|
|
public static function getAllProviders() {
|
|
|
|
$objects = id(new PhutilSymbolLoader())
|
|
|
|
->setAncestorClass('PhortunePaymentProvider')
|
|
|
|
->loadObjects();
|
|
|
|
|
|
|
|
return mpull($objects, null, 'getProviderKey');
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getEnabledProviders() {
|
|
|
|
$providers = self::getAllProviders();
|
|
|
|
foreach ($providers as $key => $provider) {
|
|
|
|
if (!$provider->isEnabled()) {
|
|
|
|
unset($providers[$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $providers;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getProvidersForAddPaymentMethod() {
|
|
|
|
$providers = self::getEnabledProviders();
|
|
|
|
foreach ($providers as $key => $provider) {
|
|
|
|
if (!$provider->canCreatePaymentMethods()) {
|
|
|
|
unset($providers[$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $providers;
|
|
|
|
}
|
|
|
|
|
2013-05-06 20:44:24 +02:00
|
|
|
public static function getProvidersForOneTimePayment() {
|
|
|
|
$providers = self::getEnabledProviders();
|
|
|
|
foreach ($providers as $key => $provider) {
|
|
|
|
if (!$provider->canProcessOneTimePayments()) {
|
|
|
|
unset($providers[$key]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $providers;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function getProviderByDigest($digest) {
|
|
|
|
$providers = self::getEnabledProviders();
|
|
|
|
foreach ($providers as $key => $provider) {
|
|
|
|
$provider_digest = PhabricatorHash::digestForIndex($key);
|
|
|
|
if ($provider_digest == $digest) {
|
|
|
|
return $provider;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2013-04-25 18:46:32 +02:00
|
|
|
abstract public function isEnabled();
|
|
|
|
|
|
|
|
final public function getProviderKey() {
|
|
|
|
return $this->getProviderType().'@'.$this->getProviderDomain();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a short string which uniquely identifies this provider's protocol
|
|
|
|
* type, like "stripe", "paypal", or "balanced".
|
|
|
|
*/
|
|
|
|
abstract public function getProviderType();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a short string which uniquely identifies the domain for this
|
|
|
|
* provider, like "stripe.com" or "google.com".
|
|
|
|
*
|
|
|
|
* This is distinct from the provider type so that protocols are not bound
|
|
|
|
* to a single domain. This is probably not relevant for payments, but this
|
|
|
|
* assumption burned us pretty hard with authentication and it's easy enough
|
|
|
|
* to avoid.
|
|
|
|
*/
|
|
|
|
abstract public function getProviderDomain();
|
|
|
|
|
|
|
|
abstract public function getPaymentMethodDescription();
|
|
|
|
abstract public function getPaymentMethodIcon();
|
|
|
|
abstract public function getPaymentMethodProviderDescription();
|
|
|
|
|
|
|
|
|
2013-04-25 18:45:43 +02:00
|
|
|
/**
|
|
|
|
* Determine of a provider can handle a payment method.
|
|
|
|
*
|
2014-07-23 02:03:09 +02:00
|
|
|
* @return bool True if this provider can apply charges to the payment method.
|
2013-04-25 18:45:43 +02:00
|
|
|
*/
|
|
|
|
abstract public function canHandlePaymentMethod(
|
|
|
|
PhortunePaymentMethod $method);
|
|
|
|
|
2014-07-23 19:36:12 +02:00
|
|
|
final public function applyCharge(
|
|
|
|
PhortunePaymentMethod $payment_method,
|
|
|
|
PhortuneCharge $charge) {
|
|
|
|
|
|
|
|
$charge->setStatus(PhortuneCharge::STATUS_CHARGING);
|
|
|
|
$charge->save();
|
|
|
|
|
|
|
|
$this->executeCharge($payment_method, $charge);
|
|
|
|
|
|
|
|
$charge->setStatus(PhortuneCharge::STATUS_CHARGED);
|
|
|
|
$charge->save();
|
|
|
|
}
|
|
|
|
|
2013-04-25 18:45:43 +02:00
|
|
|
abstract protected function executeCharge(
|
|
|
|
PhortunePaymentMethod $payment_method,
|
|
|
|
PhortuneCharge $charge);
|
|
|
|
|
2013-04-25 18:46:32 +02:00
|
|
|
|
|
|
|
/* -( Adding Payment Methods )--------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function canCreatePaymentMethods() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-25 18:49:32 +02:00
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function translateCreatePaymentMethodErrorCode($error_code) {
|
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function getCreatePaymentMethodErrorMessage($error_code) {
|
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function validateCreatePaymentMethodToken(array $token) {
|
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-25 18:46:32 +02:00
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function createPaymentMethodFromRequest(
|
|
|
|
AphrontRequest $request,
|
2013-04-25 18:49:32 +02:00
|
|
|
PhortunePaymentMethod $method,
|
|
|
|
array $token) {
|
2013-04-25 18:46:32 +02:00
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @task addmethod
|
|
|
|
*/
|
|
|
|
public function renderCreatePaymentMethodForm(
|
|
|
|
AphrontRequest $request,
|
|
|
|
array $errors) {
|
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
2013-04-25 18:46:59 +02:00
|
|
|
|
2013-05-06 20:44:24 +02:00
|
|
|
/* -( One-Time Payments )-------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
public function canProcessOneTimePayments() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function renderOneTimePaymentButton(
|
|
|
|
PhortuneAccount $account,
|
|
|
|
PhortuneCart $cart,
|
|
|
|
PhabricatorUser $user) {
|
2014-07-23 19:36:37 +02:00
|
|
|
|
|
|
|
require_celerity_resource('phortune-css');
|
|
|
|
|
|
|
|
$icon_uri = $this->getPaymentMethodIcon();
|
|
|
|
$description = $this->getPaymentMethodProviderDescription();
|
|
|
|
$details = $this->getPaymentMethodDescription();
|
|
|
|
|
|
|
|
$icon = id(new PHUIIconView())
|
|
|
|
->setImage($icon_uri)
|
|
|
|
->addClass('phortune-payment-icon');
|
|
|
|
|
|
|
|
$button = id(new PHUIButtonView())
|
|
|
|
->setSize(PHUIButtonView::BIG)
|
|
|
|
->setColor(PHUIButtonView::GREY)
|
|
|
|
->setIcon($icon)
|
|
|
|
->setText($description)
|
|
|
|
->setSubtext($details);
|
|
|
|
|
|
|
|
$uri = $this->getControllerURI(
|
|
|
|
'checkout',
|
|
|
|
array(
|
|
|
|
'cartID' => $cart->getID(),
|
|
|
|
));
|
|
|
|
|
|
|
|
return phabricator_form(
|
|
|
|
$user,
|
|
|
|
array(
|
|
|
|
'action' => $uri,
|
|
|
|
'method' => 'POST',
|
|
|
|
),
|
|
|
|
$button);
|
2013-05-06 20:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -( Controllers )-------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
|
|
final public function getControllerURI(
|
|
|
|
$action,
|
|
|
|
array $params = array()) {
|
|
|
|
|
|
|
|
$digest = PhabricatorHash::digestForIndex($this->getProviderKey());
|
|
|
|
|
2014-07-23 02:03:09 +02:00
|
|
|
$app = PhabricatorApplication::getByClass('PhabricatorPhortuneApplication');
|
2013-05-06 20:44:24 +02:00
|
|
|
$path = $app->getBaseURI().'provider/'.$digest.'/'.$action.'/';
|
|
|
|
|
|
|
|
$uri = new PhutilURI($path);
|
|
|
|
$uri->setQueryParams($params);
|
|
|
|
|
|
|
|
return PhabricatorEnv::getURI((string)$uri);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function canRespondToControllerAction($action) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function processControllerRequest(
|
|
|
|
PhortuneProviderController $controller,
|
|
|
|
AphrontRequest $request) {
|
|
|
|
throw new PhortuneNotImplementedException($this);
|
|
|
|
}
|
|
|
|
|
2013-04-25 18:45:43 +02:00
|
|
|
}
|