mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-29 00:40:57 +01:00
Implement Balanced Payments as a PhortunePaymentProvider
Summary: Allows Balanced payment methods to be added. This works essentially the same way as Stripe, except everything is a little bit different. Slightly more stuff could be shared, but I feel //mostly// good about this. I'll probably do a bit more cleanup next. Some of the error handling is messy, in particular. Ref T2787. Test Plan: Added Balanced and Stripe payment methods. Reviewers: btrahan, chad Reviewed By: btrahan CC: aran Maniphest Tasks: T2787 Differential Revision: https://secure.phabricator.com/D5765
This commit is contained in:
parent
23786784ef
commit
6efba56448
9 changed files with 308 additions and 35 deletions
|
@ -1274,6 +1274,20 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js',
|
'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js',
|
||||||
),
|
),
|
||||||
|
'javelin-behavior-balanced-payment-form' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/2a850a31/rsrc/js/application/phortune/behavior-balanced-payment-form.js',
|
||||||
|
'type' => 'js',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
2 => 'javelin-json',
|
||||||
|
3 => 'javelin-workflow',
|
||||||
|
4 => 'phortune-credit-card-form',
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/js/application/phortune/behavior-balanced-payment-form.js',
|
||||||
|
),
|
||||||
'javelin-behavior-conpherence-drag-and-drop-photo' =>
|
'javelin-behavior-conpherence-drag-and-drop-photo' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/9e3eb1cd/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
|
'uri' => '/res/9e3eb1cd/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
|
||||||
|
@ -2258,7 +2272,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-stripe-payment-form' =>
|
'javelin-behavior-stripe-payment-form' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/62dc91b4/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
|
'uri' => '/res/2ae12d96/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
|
||||||
'type' => 'js',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -1219,6 +1219,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhabricatorOAuthConfigOptions' => 'applications/config/option/PhabricatorPhabricatorOAuthConfigOptions.php',
|
'PhabricatorPhabricatorOAuthConfigOptions' => 'applications/config/option/PhabricatorPhabricatorOAuthConfigOptions.php',
|
||||||
'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php',
|
'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php',
|
||||||
'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php',
|
'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php',
|
||||||
|
'PhabricatorPhortuneConfigOptions' => 'applications/phortune/option/PhabricatorPhortuneConfigOptions.php',
|
||||||
'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php',
|
'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php',
|
||||||
'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
|
'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
|
||||||
'PhabricatorPinboardItemView' => 'view/layout/PhabricatorPinboardItemView.php',
|
'PhabricatorPinboardItemView' => 'view/layout/PhabricatorPinboardItemView.php',
|
||||||
|
@ -1400,7 +1401,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php',
|
'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php',
|
||||||
'PhabricatorStorageManagementWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php',
|
'PhabricatorStorageManagementWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php',
|
||||||
'PhabricatorStoragePatch' => 'infrastructure/storage/management/PhabricatorStoragePatch.php',
|
'PhabricatorStoragePatch' => 'infrastructure/storage/management/PhabricatorStoragePatch.php',
|
||||||
'PhabricatorStripeConfigOptions' => 'applications/phortune/option/PhabricatorStripeConfigOptions.php',
|
|
||||||
'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
|
'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
|
||||||
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
|
'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
|
||||||
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
|
'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
|
||||||
|
@ -1580,6 +1580,7 @@ phutil_register_library_map(array(
|
||||||
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
|
'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
|
||||||
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
|
'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
|
||||||
'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php',
|
'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php',
|
||||||
|
'PhortuneBalancedPaymentProvider' => 'applications/phortune/provider/PhortuneBalancedPaymentProvider.php',
|
||||||
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
|
'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
|
||||||
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
|
||||||
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
|
'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
|
||||||
|
@ -2923,6 +2924,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorPhabricatorOAuthConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhabricatorOAuthConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
|
'PhabricatorPhortuneConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||||
'PhabricatorPinboardItemView' => 'AphrontView',
|
'PhabricatorPinboardItemView' => 'AphrontView',
|
||||||
|
@ -3091,7 +3093,6 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
|
'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
|
||||||
'PhabricatorStripeConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
|
||||||
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
|
'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
|
||||||
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
|
'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
|
||||||
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
|
'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
|
||||||
|
@ -3302,6 +3303,7 @@ phutil_register_library_map(array(
|
||||||
'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
|
'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'PhortuneAccountViewController' => 'PhortuneController',
|
'PhortuneAccountViewController' => 'PhortuneController',
|
||||||
|
'PhortuneBalancedPaymentProvider' => 'PhortunePaymentProvider',
|
||||||
'PhortuneCart' => 'PhortuneDAO',
|
'PhortuneCart' => 'PhortuneDAO',
|
||||||
'PhortuneCharge' => 'PhortuneDAO',
|
'PhortuneCharge' => 'PhortuneDAO',
|
||||||
'PhortuneController' => 'PhabricatorController',
|
'PhortuneController' => 'PhabricatorController',
|
||||||
|
|
|
@ -5,7 +5,7 @@ final class PhortuneNotImplementedException extends Exception {
|
||||||
public function __construct(PhortunePaymentProvider $provider) {
|
public function __construct(PhortunePaymentProvider $provider) {
|
||||||
$class = get_class($provider);
|
$class = get_class($provider);
|
||||||
return parent::__construct(
|
return parent::__construct(
|
||||||
"Provider '{$provider}' does not implement this method.");
|
"Provider '{$class}' does not implement this method.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorPhortuneConfigOptions
|
||||||
|
extends PhabricatorApplicationConfigOptions {
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return pht("Phortune");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription() {
|
||||||
|
return pht("Configure payments and billing.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOptions() {
|
||||||
|
return array(
|
||||||
|
$this->newOption('phortune.stripe.publishable-key', 'string', null)
|
||||||
|
->setLocked(true)
|
||||||
|
->setDescription(pht('Stripe publishable key.')),
|
||||||
|
$this->newOption('phortune.stripe.secret-key', 'string', null)
|
||||||
|
->setHidden(true)
|
||||||
|
->setDescription(pht('Stripe secret key.')),
|
||||||
|
$this->newOption('phortune.balanced.marketplace-uri', 'string', null)
|
||||||
|
->setLocked(true)
|
||||||
|
->setDescription(pht('Balanced Marketplace URI.')),
|
||||||
|
$this->newOption('phortune.balanced.secret-key', 'string', null)
|
||||||
|
->setHidden(true)
|
||||||
|
->setDescription(pht('Balanced secret key.')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class PhabricatorStripeConfigOptions
|
|
||||||
extends PhabricatorApplicationConfigOptions {
|
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return pht("Integration with Stripe");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDescription() {
|
|
||||||
return pht("Configure Stripe payments.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getOptions() {
|
|
||||||
return array(
|
|
||||||
$this->newOption('stripe.publishable-key', 'string', null)
|
|
||||||
->setDescription(
|
|
||||||
pht('Stripe publishable key.')),
|
|
||||||
$this->newOption('stripe.secret-key', 'string', null)
|
|
||||||
->setDescription(
|
|
||||||
pht('Stripe secret key.')),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhortuneBalancedPaymentProvider extends PhortunePaymentProvider {
|
||||||
|
|
||||||
|
public function isEnabled() {
|
||||||
|
return $this->getMarketplaceURI() &&
|
||||||
|
$this->getSecretKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProviderType() {
|
||||||
|
return 'balanced';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProviderDomain() {
|
||||||
|
return 'balancedpayments.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentMethodDescription() {
|
||||||
|
return pht('Add Credit or Debit Card');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentMethodIcon() {
|
||||||
|
return celerity_get_resource_uri('/rsrc/image/phortune/balanced.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPaymentMethodProviderDescription() {
|
||||||
|
return pht('Processed by Balanced');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function canHandlePaymentMethod(PhortunePaymentMethod $method) {
|
||||||
|
$type = $method->getMetadataValue('type');
|
||||||
|
return ($type === 'balanced.account');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function executeCharge(
|
||||||
|
PhortunePaymentMethod $method,
|
||||||
|
PhortuneCharge $charge) {
|
||||||
|
throw new PhortuneNotImplementedException($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getMarketplaceURI() {
|
||||||
|
return PhabricatorEnv::getEnvConfig('phortune.balanced.marketplace-uri');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSecretKey() {
|
||||||
|
return PhabricatorEnv::getEnvConfig('phortune.balanced.secret-key');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -( Adding Payment Methods )--------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function canCreatePaymentMethods() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phutil-external-symbol class Balanced\Settings
|
||||||
|
* @phutil-external-symbol class Balanced\Marketplace
|
||||||
|
* @phutil-external-symbol class RESTful\Exceptions\HTTPError
|
||||||
|
*/
|
||||||
|
public function createPaymentMethodFromRequest(
|
||||||
|
AphrontRequest $request,
|
||||||
|
PhortunePaymentMethod $method) {
|
||||||
|
|
||||||
|
$card_errors = $request->getStr('cardErrors');
|
||||||
|
$balanced_data = $request->getStr('balancedCardData');
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
if ($card_errors) {
|
||||||
|
$raw_errors = json_decode($card_errors);
|
||||||
|
$errors = $this->parseRawCreatePaymentMethodErrors($raw_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$data = json_decode($balanced_data, true);
|
||||||
|
if (!is_array($data)) {
|
||||||
|
$errors[] = pht('An error occurred decoding card data.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$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();
|
||||||
|
$author_phid = $method->getAuthorPHID();
|
||||||
|
$description = $account_phid.':'.$author_phid;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Balanced\Settings::$api_key = $this->getSecretKey();
|
||||||
|
$buyer = Balanced\Marketplace::mine()->createBuyer(
|
||||||
|
null,
|
||||||
|
$data['uri'],
|
||||||
|
array(
|
||||||
|
'description' => $description,
|
||||||
|
));
|
||||||
|
|
||||||
|
} catch (RESTful\Exceptions\HTTPError $error) {
|
||||||
|
// NOTE: This exception doesn't print anything meaningful if it escapes
|
||||||
|
// to top level. Replace it with something slightly readable.
|
||||||
|
throw new Exception($error->response->body->description);
|
||||||
|
}
|
||||||
|
|
||||||
|
$exp_string = $data['expiration_year'].'-'.$data['expiration_month'];
|
||||||
|
$epoch = strtotime($exp_string);
|
||||||
|
|
||||||
|
$method
|
||||||
|
->setName($data['brand'].' / '.$data['last_four'])
|
||||||
|
->setExpiresEpoch($epoch)
|
||||||
|
->setMetadata(
|
||||||
|
array(
|
||||||
|
'type' => 'balanced.account',
|
||||||
|
'balanced.accountURI' => $buyer->uri,
|
||||||
|
'balanced.cardURI' => $data['uri'],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderCreatePaymentMethodForm(
|
||||||
|
AphrontRequest $request,
|
||||||
|
array $errors) {
|
||||||
|
|
||||||
|
$ccform = id(new PhortuneCreditCardForm())
|
||||||
|
->setUser($request->getUser())
|
||||||
|
->setCardNumberError(isset($errors['number']) ? pht('Invalid') : true)
|
||||||
|
->setCardCVCError(isset($errors['cvc']) ? pht('Invalid') : true)
|
||||||
|
->setCardExpirationError(isset($errors['exp']) ? pht('Invalid') : null)
|
||||||
|
->addScript('https://js.balancedpayments.com/v1/balanced.js');
|
||||||
|
|
||||||
|
Javelin::initBehavior(
|
||||||
|
'balanced-payment-form',
|
||||||
|
array(
|
||||||
|
'balancedMarketplaceURI' => $this->getMarketplaceURI(),
|
||||||
|
'formID' => $ccform->getFormID(),
|
||||||
|
));
|
||||||
|
|
||||||
|
return $ccform->buildForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseRawCreatePaymentMethodErrors(array $raw_errors) {
|
||||||
|
$errors = array();
|
||||||
|
|
||||||
|
foreach ($raw_errors as $error) {
|
||||||
|
switch ($error) {
|
||||||
|
case 'number':
|
||||||
|
$errors[$error] = pht('Card number is incorrect or invalid.');
|
||||||
|
break;
|
||||||
|
case 'cvc':
|
||||||
|
$errors[$error] = pht('CVC code is incorrect or invalid.');
|
||||||
|
break;
|
||||||
|
case 'exp':
|
||||||
|
$errors[$error] = pht('Card expiration date is incorrect.');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$errors[] = $error;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -59,11 +59,11 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPublishableKey() {
|
private function getPublishableKey() {
|
||||||
return PhabricatorEnv::getEnvConfig('stripe.publishable-key');
|
return PhabricatorEnv::getEnvConfig('phortune.stripe.publishable-key');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getSecretKey() {
|
private function getSecretKey() {
|
||||||
return PhabricatorEnv::getEnvConfig('stripe.secret-key');
|
return PhabricatorEnv::getEnvConfig('phortune.stripe.secret-key');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,11 +90,13 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
if ($card_errors) {
|
if ($card_errors) {
|
||||||
$raw_errors = json_decode($card_errors);
|
$raw_errors = json_decode($card_errors);
|
||||||
$errors = $this->parseRawCreatePaymentMethodErrors($raw_errors);
|
$errors = $this->parseRawCreatePaymentMethodErrors($raw_errors);
|
||||||
} else if (!$stripe_token) {
|
|
||||||
$errors[] = pht('There was an unknown error processing your card.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$secret_key = $this->getSecretKey();
|
if (!$errors) {
|
||||||
|
if (!$stripe_token) {
|
||||||
|
$errors[] = pht('There was an unknown error processing your card.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$root = dirname(phutil_get_library_root('phabricator'));
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
@ -102,6 +104,8 @@ final class PhortuneStripePaymentProvider extends PhortunePaymentProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First, make sure the token is valid.
|
// First, make sure the token is valid.
|
||||||
|
$secret_key = $this->getSecretKey();
|
||||||
|
|
||||||
$info = id(new Stripe_Token())->retrieve($stripe_token, $secret_key);
|
$info = id(new Stripe_Token())->retrieve($stripe_token, $secret_key);
|
||||||
|
|
||||||
$account_phid = $method->getAccountPHID();
|
$account_phid = $method->getAccountPHID();
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* @provides javelin-behavior-balanced-payment-form
|
||||||
|
* @requires javelin-behavior
|
||||||
|
* javelin-dom
|
||||||
|
* javelin-json
|
||||||
|
* javelin-workflow
|
||||||
|
* phortune-credit-card-form
|
||||||
|
*/
|
||||||
|
|
||||||
|
JX.behavior('balanced-payment-form', function(config) {
|
||||||
|
balanced.init(config.balancedMarketplaceURI);
|
||||||
|
|
||||||
|
var root = JX.$(config.formID);
|
||||||
|
var ccform = new JX.PhortuneCreditCardForm(root);
|
||||||
|
|
||||||
|
var onsubmit = function(e) {
|
||||||
|
e.kill();
|
||||||
|
|
||||||
|
var cardData = ccform.getCardData();
|
||||||
|
var errors = [];
|
||||||
|
|
||||||
|
if (!balanced.card.isCardNumberValid(cardData.number)) {
|
||||||
|
errors.push('number');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!balanced.card.isSecurityCodeValid(cardData.number, cardData.cvc)) {
|
||||||
|
errors.push('cvc');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!balanced.card.isExpiryValid(cardData.month, cardData.year)) {
|
||||||
|
errors.push('expiry');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length) {
|
||||||
|
JX.Workflow
|
||||||
|
.newFromForm(root, {cardErrors: JX.JSON.stringify(errors)})
|
||||||
|
.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
card_number: cardData.number,
|
||||||
|
security_code: cardData.cvc,
|
||||||
|
expiration_month: cardData.month,
|
||||||
|
expiration_year: cardData.year
|
||||||
|
};
|
||||||
|
|
||||||
|
balanced.card.create(data, onresponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
var onresponse = function(response) {
|
||||||
|
|
||||||
|
var errors = [];
|
||||||
|
if (response.error) {
|
||||||
|
errors = [response.error.type];
|
||||||
|
} else if (response.status != 201) {
|
||||||
|
errors = ['balanced:' + response.status];
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
cardErrors: JX.JSON.stringify(errors),
|
||||||
|
balancedCardData: JX.JSON.stringify(response.data)
|
||||||
|
};
|
||||||
|
|
||||||
|
JX.Workflow
|
||||||
|
.newFromForm(root, params)
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
JX.DOM.listen(root, 'submit', null, onsubmit);
|
||||||
|
});
|
|
@ -59,8 +59,13 @@ JX.behavior('stripe-payment-form', function(config) {
|
||||||
token = response.id;
|
token = response.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var params = {
|
||||||
|
cardErrors: JX.JSON.stringify(errors),
|
||||||
|
stripeToken: token
|
||||||
|
};
|
||||||
|
|
||||||
JX.Workflow
|
JX.Workflow
|
||||||
.newFromForm(root, {cardErrors: errors, stripeToken: token})
|
.newFromForm(root, params)
|
||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue