Add Braintree support

This commit is contained in:
Joshua Dwire 2016-04-26 19:59:52 -04:00
parent af415afd2f
commit fe2a1fe66a
32 changed files with 389 additions and 74 deletions

View File

@ -143,7 +143,8 @@ class ClientController extends BaseController
'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0, 'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0,
'hasQuotes' => Invoice::scope()->where('is_quote', '=', true)->whereClientId($client->id)->count() > 0, 'hasQuotes' => Invoice::scope()->where('is_quote', '=', true)->whereClientId($client->id)->count() > 0,
'hasTasks' => Task::scope()->whereClientId($client->id)->count() > 0, 'hasTasks' => Task::scope()->whereClientId($client->id)->count() > 0,
'gatewayLink' => $client->getGatewayLink(), 'gatewayLink' => $client->getGatewayLink($accountGateway),
'gateway' => $accountGateway
); );
return View::make('clients.show', $data); return View::make('clients.show', $data);

View File

@ -200,6 +200,10 @@ class PaymentController extends BaseController
'showAddress' => $accountGateway->show_address, 'showAddress' => $accountGateway->show_address,
]; ];
if ($gateway->id = GATEWAY_BRAINTREE) {
$data['braintreeClientToken'] = $this->paymentService->getBraintreeClientToken($account);
}
return View::make('payments.payment', $data); return View::make('payments.payment', $data);
} }
@ -377,7 +381,7 @@ class PaymentController extends BaseController
'last_name' => 'required', 'last_name' => 'required',
]; ];
if ( ! Input::get('stripeToken')) { if ( ! Input::get('stripeToken') && ! Input::get('payment_method_nonce')) {
$rules = array_merge( $rules = array_merge(
$rules, $rules,
[ [
@ -451,6 +455,28 @@ class PaymentController extends BaseController
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv')); return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
} }
} }
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
if ($token = Input::get('payment_method_nonce')) {
$details['token'] = $token;
unset($details['card']);
}
if ($useToken) {
$details['customerId'] = $customerId = $client->getGatewayToken();
$customer = $gateway->findCustomer($customerId)->send();
$details['paymentMethodToken'] = $customer->getData()->paymentMethods[0]->token;
unset($details['token']);
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
$token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference);
if ($token) {
$details['paymentMethodToken'] = $token;
$details['customerId'] = $customerReference;
unset($details['token']);
} else {
$this->error('Token-No-Ref', $this->paymentService->lastError, $accountGateway);
return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv'));
}
}
} }
$response = $gateway->purchase($details)->send(); $response = $gateway->purchase($details)->send();

View File

@ -305,7 +305,7 @@ class PublicClientController extends BaseController
public function paymentIndex() public function paymentIndex()
{ {
if (!$invitation = $this->getInvitation()) { if (!$invitation = $this->getInGvitation()) {
return $this->returnError(); return $this->returnError();
} }
$account = $invitation->account; $account = $invitation->account;

View File

@ -490,7 +490,7 @@ if (!defined('CONTACT_EMAIL')) {
define('CARD_DISCOVER', 5); define('CARD_DISCOVER', 5);
define('CARD_JCB', 6); define('CARD_JCB', 6);
define('CARD_LASER', 7); define('CARD_LASER', 7);
define('CARD_MAISTRO', 8); define('CARD_MAESTRO', 8);
define('CARD_MASTERCARD', 9); define('CARD_MASTERCARD', 9);
define('CARD_SOLO', 10); define('CARD_SOLO', 10);
define('CARD_SWITCH', 11); define('CARD_SWITCH', 11);
@ -560,6 +560,7 @@ if (!defined('CONTACT_EMAIL')) {
define('GATEWAY_DWOLLA', 43); define('GATEWAY_DWOLLA', 43);
define('GATEWAY_CHECKOUT_COM', 47); define('GATEWAY_CHECKOUT_COM', 47);
define('GATEWAY_CYBERSOURCE', 49); define('GATEWAY_CYBERSOURCE', 49);
define('GATEWAY_BRAINTREE', 62);
define('EVENT_CREATE_CLIENT', 1); define('EVENT_CREATE_CLIENT', 1);
define('EVENT_CREATE_INVOICE', 2); define('EVENT_CREATE_INVOICE', 2);

View File

@ -1199,9 +1199,9 @@ class Account extends Eloquent
return false; return false;
} }
public function showTokenCheckbox() public function showTokenCheckbox(&$storage_gateway = null)
{ {
if (!$this->isGatewayConfigured(GATEWAY_STRIPE)) { if (!$this->getTokenGatewayId()) {
return false; return false;
} }
@ -1209,6 +1209,25 @@ class Account extends Eloquent
|| $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT; || $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;
} }
public function getTokenGatewayId() {
if ($this->isGatewayConfigured(GATEWAY_STRIPE)) {
return GATEWAY_STRIPE;
} elseif ($this->isGatewayConfigured(GATEWAY_BRAINTREE)) {
return GATEWAY_BRAINTREE;
} else {
return false;
}
}
public function getTokenGateway() {
$gatewayId = $this->getTokenGatewayId();
if (!$gatewayId) {
return;
}
return $this->getGatewayConfig($gatewayId);
}
public function selectTokenCheckbox() public function selectTokenCheckbox()
{ {
return $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT; return $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;

View File

@ -254,16 +254,15 @@ class Client extends EntityModel
} }
public function getGatewayToken() public function getGatewayToken(&$accountGateway = null)
{ {
$this->account->load('account_gateways'); $this->account->load('account_gateways');
if (!count($this->account->account_gateways)) { if (!count($this->account->account_gateways)) {
return false; return false;
} }
$accountGateway = $this->account->getTokenGateway();
$accountGateway = $this->account->getGatewayConfig(GATEWAY_STRIPE);
if (!$accountGateway) { if (!$accountGateway) {
return false; return false;
} }
@ -274,10 +273,22 @@ class Client extends EntityModel
return $token ? $token->token : false; return $token ? $token->token : false;
} }
public function getGatewayLink() public function getGatewayLink(&$accountGateway = null)
{ {
$token = $this->getGatewayToken(); $token = $this->getGatewayToken($accountGateway);
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false; if (!$token) {
return false;
}
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
return "https://dashboard.stripe.com/customers/{$token}";
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
$merchantId = $accountGateway->getConfig()->merchantId;
$testMode = $accountGateway->getConfig()->testMode;
return $testMode ? "https://sandbox.braintreegateway.com/merchants/{$merchantId}/customers/{$token}" : "https://www.braintreegateway.com/merchants/{$merchantId}/customers/{$token}";
} else {
return false;
}
} }
public function getAmount() public function getAmount()

View File

@ -157,15 +157,26 @@ class PaymentService extends BaseService
public function createToken($gateway, $details, $accountGateway, $client, $contactId, &$customerReference = null) public function createToken($gateway, $details, $accountGateway, $client, $contactId, &$customerReference = null)
{ {
$tokenResponse = $gateway->createCard($details)->send(); if ($accountGateway->gateway->id == GATEWAY_STRIPE) {
$cardReference = $tokenResponse->getCardReference(); $tokenResponse = $gateway->createCard($details)->send();
$customerReference = $tokenResponse->getCustomerReference(); $cardReference = $tokenResponse->getCardReference();
$customerReference = $tokenResponse->getCustomerReference();
if ($customerReference == $cardReference) {
// This customer was just created; find the card if ($customerReference == $cardReference) {
$data = $tokenResponse->getData(); // This customer was just created; find the card
if(!empty($data['default_source'])) { $data = $tokenResponse->getData();
$cardReference = $data['default_source']; if (!empty($data['default_source'])) {
$cardReference = $data['default_source'];
}
}
} elseif ($accountGateway->gateway->id == GATEWAY_BRAINTREE) {
$tokenResponse = $gateway->createCustomer(array('customerData'=>array()))->send();
if ($tokenResponse->isSuccessful()) {
$details['customerId'] = $customerReference = $tokenResponse->getCustomerData()->id;
$tokenResponse = $gateway->createPaymentMethod($details)->send();
$cardReference = $tokenResponse->getData()->paymentMethod->token;
} }
} }
@ -214,6 +225,18 @@ class PaymentService extends BaseService
return $token; return $token;
} }
public function getBraintreeClientToken($account)
{
$token = false;
$accountGateway = $account->getGatewayConfig(GATEWAY_BRAINTREE);
$gateway = $this->createGateway($accountGateway);
$token = $gateway->clientToken()->send()->getToken();
return $token;
}
public function createPayment($invitation, $accountGateway, $ref, $payerId = null, $paymentDetails = null, $purchaseResponse = null) public function createPayment($invitation, $accountGateway, $ref, $payerId = null, $paymentDetails = null, $purchaseResponse = null)
{ {
$invoice = $invitation->invoice; $invoice = $invitation->invoice;
@ -228,7 +251,7 @@ class PaymentService extends BaseService
$payment->transaction_reference = $ref; $payment->transaction_reference = $ref;
$payment->payment_date = date_create()->format('Y-m-d'); $payment->payment_date = date_create()->format('Y-m-d');
if (!empty($paymentDetails['card'])) { if (!empty($paymentDetails['card'])) {
$card = $paymentDetails['card']; $card = $paymentDetails['card'];
$payment->last4 = substr($card->number, -4); $payment->last4 = substr($card->number, -4);
$year = $card->expiryYear; $year = $card->expiryYear;
@ -255,7 +278,7 @@ class PaymentService extends BaseService
'MasterCard' => CARD_MASTERCARD, 'MasterCard' => CARD_MASTERCARD,
'Discover' => CARD_DISCOVER, 'Discover' => CARD_DISCOVER,
'JCB' => CARD_JCB, 'JCB' => CARD_JCB,
'Diners Club' => CARD_DINERS_CLUB 'Diners Club' => CARD_DINERS_CLUB,
); );
if (!empty($stripe_card_types[$card['brand']])) { if (!empty($stripe_card_types[$card['brand']])) {
@ -264,6 +287,31 @@ class PaymentService extends BaseService
$payment->card_type_id = CARD_UNKNOWN; $payment->card_type_id = CARD_UNKNOWN;
} }
} }
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
$card = $purchaseResponse->getData()->transaction->creditCardDetails;
$payment->last4 = $card->last4;
$payment->expiration = $card->expirationYear . '-' . $card->expirationMonth . '-00';
$braintree_card_types = array(
'Visa' => CARD_VISA,
'American Express' => CARD_AMERICAN_EXPRESS,
'MasterCard' => CARD_MASTERCARD,
'Discover' => CARD_DISCOVER,
'JCB' => CARD_JCB,
'Diners Club' => CARD_DINERS_CLUB,
'Carte Blanche' => CARD_CARTE_BLANCHE,
'China UnionPay' => CARD_UNIONPAY,
'Laser' => CARD_LASER,
'Maestro' => CARD_MAESTRO,
'Solo' => CARD_SOLO,
'Switch' => CARD_SWITCH,
);
if (!empty($braintree_card_types[$card->cardType])) {
$payment->card_type_id = $braintree_card_types[$card->cardType];
} else {
$payment->card_type_id = CARD_UNKNOWN;
}
} }
if ($payerId) { if ($payerId) {
@ -363,7 +411,7 @@ class PaymentService extends BaseService
$client = $invoice->client; $client = $invoice->client;
$account = $invoice->account; $account = $invoice->account;
$invitation = $invoice->invitations->first(); $invitation = $invoice->invitations->first();
$accountGateway = $account->getGatewayConfig(GATEWAY_STRIPE); $accountGateway = $account->getTokenGateway();
$token = $client->getGatewayToken(); $token = $client->getGatewayToken();
if (!$invitation || !$accountGateway || !$token) { if (!$invitation || !$accountGateway || !$token) {
@ -375,12 +423,21 @@ class PaymentService extends BaseService
$details = $this->getPaymentDetails($invitation, $accountGateway); $details = $this->getPaymentDetails($invitation, $accountGateway);
$details['customerReference'] = $token; $details['customerReference'] = $token;
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
$details['customerReference'] = $token;
} elseif ($accountGateway->gateway_id == GATEWAY_BRAINTREE) {
$details['customerId'] = $token;
$customer = $gateway->findCustomer($token)->send();
$details['paymentMethodToken'] = $customer->getData()->paymentMethods[0]->token;
}
// submit purchase/get response // submit purchase/get response
$response = $gateway->purchase($details)->send(); $response = $gateway->purchase($details)->send();
if ($response->isSuccessful()) { if ($response->isSuccessful()) {
$ref = $response->getTransactionReference(); $ref = $response->getTransactionReference();
return $this->createPayment($invitation, $accountGateway, $ref, $details, $response); return $this->createPayment($invitation, $accountGateway, $ref, null, $details, $response);
} else { } else {
return false; return false;
} }

View File

@ -72,7 +72,8 @@
"asgrim/ofxparser": "^1.1", "asgrim/ofxparser": "^1.1",
"league/flysystem-aws-s3-v3": "~1.0", "league/flysystem-aws-s3-v3": "~1.0",
"league/flysystem-rackspace": "~1.0", "league/flysystem-rackspace": "~1.0",
"barracudanetworks/archivestream-php": "^1.0" "barracudanetworks/archivestream-php": "^1.0",
"omnipay/braintree": "~2.0@dev"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.0", "phpunit/phpunit": "~4.0",
@ -122,4 +123,4 @@
"config": { "config": {
"preferred-install": "dist" "preferred-install": "dist"
} }
} }

119
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "607b25b09aee82ac769bd942fac91ba6", "hash": "e2b43d6bd5e87dfb9b3be07e89a2bd9f",
"content-hash": "122f3f59beb2286159145d219dbcbc90", "content-hash": "480134957ff37fd0f46b5d90909da660",
"packages": [ "packages": [
{ {
"name": "agmscode/omnipay-agms", "name": "agmscode/omnipay-agms",
@ -558,6 +558,53 @@
], ],
"time": "2016-03-03 14:38:04" "time": "2016-03-03 14:38:04"
}, },
{
"name": "braintree/braintree_php",
"version": "3.11.0",
"source": {
"type": "git",
"url": "https://github.com/braintree/braintree_php.git",
"reference": "2ab7e41d8d31286fa64bae7279a8e785a40b1be4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/braintree/braintree_php/zipball/2ab7e41d8d31286fa64bae7279a8e785a40b1be4",
"reference": "2ab7e41d8d31286fa64bae7279a8e785a40b1be4",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-dom": "*",
"ext-hash": "*",
"ext-openssl": "*",
"ext-xmlwriter": "*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"type": "library",
"autoload": {
"psr-0": {
"Braintree": "lib/"
},
"psr-4": {
"Braintree\\": "lib/Braintree"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Braintree",
"homepage": "http://www.braintreepayments.com"
}
],
"description": "Braintree PHP Client Library",
"time": "2016-04-12 20:39:36"
},
{ {
"name": "cardgate/omnipay-cardgate", "name": "cardgate/omnipay-cardgate",
"version": "v2.0.0", "version": "v2.0.0",
@ -2338,7 +2385,7 @@
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/e368d262887dbb2fdfaf710880571ede51e9c0e6", "url": "https://api.github.com/repos/Intervention/image/zipball/22088b04728a039bd1fc32f7e79a89a118b78698",
"reference": "e368d262887dbb2fdfaf710880571ede51e9c0e6", "reference": "e368d262887dbb2fdfaf710880571ede51e9c0e6",
"shasum": "" "shasum": ""
}, },
@ -4277,6 +4324,69 @@
], ],
"time": "2016-03-10 03:16:04" "time": "2016-03-10 03:16:04"
}, },
{
"name": "omnipay/braintree",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-braintree.git",
"reference": "e4b4027c6a9e6443833490d0d51fd530f0a19f62"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/omnipay-braintree/zipball/e4b4027c6a9e6443833490d0d51fd530f0a19f62",
"reference": "e4b4027c6a9e6443833490d0d51fd530f0a19f62",
"shasum": ""
},
"require": {
"braintree/braintree_php": "^2.39|^3.0",
"omnipay/common": "~2.0"
},
"require-dev": {
"omnipay/tests": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Omnipay\\Braintree\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
},
{
"name": "Kayla Daniels",
"email": "kayladnls@gmail.com"
},
{
"name": "Omnipay Contributors",
"homepage": "https://github.com/thephpleague/omnipay-braintree/contributors"
}
],
"description": "Braintree gateway for Omnipay payment processing library",
"homepage": "https://github.com/thephpleague/omnipay-braintree",
"keywords": [
"braintree",
"gateway",
"merchant",
"omnipay",
"pay",
"payment",
"purchase"
],
"time": "2016-02-25 20:54:09"
},
{ {
"name": "omnipay/buckaroo", "name": "omnipay/buckaroo",
"version": "v2.0.1", "version": "v2.0.1",
@ -9894,7 +10004,8 @@
"meebio/omnipay-secure-trading": 20, "meebio/omnipay-secure-trading": 20,
"labs7in0/omnipay-wechat": 20, "labs7in0/omnipay-wechat": 20,
"laracasts/presenter": 20, "laracasts/presenter": 20,
"jlapp/swaggervel": 20 "jlapp/swaggervel": 20,
"omnipay/braintree": 20
}, },
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,

View File

@ -48,6 +48,7 @@ class PaymentLibrariesSeeder extends Seeder
['name' => 'SecPay', 'provider' => 'SecPay', 'payment_library_id' => 1], ['name' => 'SecPay', 'provider' => 'SecPay', 'payment_library_id' => 1],
['name' => 'WeChat Express', 'provider' => 'WeChat_Express', 'payment_library_id' => 1], ['name' => 'WeChat Express', 'provider' => 'WeChat_Express', 'payment_library_id' => 1],
['name' => 'WePay', 'provider' => 'WePay', 'payment_library_id' => 1], ['name' => 'WePay', 'provider' => 'WePay', 'payment_library_id' => 1],
['name' => 'Braintree', 'provider' => 'Braintree', 'payment_library_id' => 1],
]; ];
foreach ($gateways as $gateway) { foreach ($gateways as $gateway) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,7 +17,6 @@
| loading any of our classes later on. It feels nice to relax. | loading any of our classes later on. It feels nice to relax.
| |
*/ */
require __DIR__.'/../bootstrap/autoload.php'; require __DIR__.'/../bootstrap/autoload.php';
/* /*

View File

@ -516,11 +516,11 @@ return array(
'token_billing_3' => 'Fravalg - checkboks er vist og valgt', 'token_billing_3' => 'Fravalg - checkboks er vist og valgt',
'token_billing_4' => 'Altid', 'token_billing_4' => 'Altid',
'token_billing_checkbox' => 'Opbevar kreditkort oplysninger', 'token_billing_checkbox' => 'Opbevar kreditkort oplysninger',
'view_in_stripe' => 'Vis i Stripe ', 'view_in_gateway' => 'Vis i :gateway',
'use_card_on_file' => 'Brug allerede gemt kort', 'use_card_on_file' => 'Brug allerede gemt kort',
'edit_payment_details' => 'Redigér betalings detaljer', 'edit_payment_details' => 'Redigér betalings detaljer',
'token_billing' => 'Gem kort detaljer', 'token_billing' => 'Gem kort detaljer',
'token_billing_secure' => 'Kort data er opbevaret sikkert hos :stripe_link', 'token_billing_secure' => 'Kort data er opbevaret sikkert hos :link',
'support' => 'Kundeservice', 'support' => 'Kundeservice',
'contact_information' => 'Kontakt information', 'contact_information' => 'Kontakt information',

View File

@ -516,11 +516,11 @@ return array(
'token_billing_3' => 'Opt-out - Kontrollkästchen wird angezeigt und ist ausgewählt', 'token_billing_3' => 'Opt-out - Kontrollkästchen wird angezeigt und ist ausgewählt',
'token_billing_4' => 'Immer', 'token_billing_4' => 'Immer',
'token_billing_checkbox' => 'Kreditkarteninformationen speichern', 'token_billing_checkbox' => 'Kreditkarteninformationen speichern',
'view_in_stripe' => 'Auf Stripe anzeigen', 'view_in_gateway' => 'Auf :gateway anzeigen',
'use_card_on_file' => 'Verwende gespeicherte Kreditkarte', 'use_card_on_file' => 'Verwende gespeicherte Kreditkarte',
'edit_payment_details' => 'Zahlungsdetails bearbeiten', 'edit_payment_details' => 'Zahlungsdetails bearbeiten',
'token_billing' => 'Kreditkarte merken', 'token_billing' => 'Kreditkarte merken',
'token_billing_secure' => 'Die Daten werden sicher von :stripe_link gespeichert.', 'token_billing_secure' => 'Die Daten werden sicher von :link gespeichert.',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Kontakt-Informationen', 'contact_information' => 'Kontakt-Informationen',

View File

@ -444,11 +444,11 @@ $LANG = array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected', 'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Always', 'token_billing_4' => 'Always',
'token_billing_checkbox' => 'Store credit card details', 'token_billing_checkbox' => 'Store credit card details',
'view_in_stripe' => 'View in Stripe', 'view_in_gateway' => 'View in :gateway',
'use_card_on_file' => 'Use card on file', 'use_card_on_file' => 'Use card on file',
'edit_payment_details' => 'Edit payment details', 'edit_payment_details' => 'Edit payment details',
'token_billing' => 'Save card details', 'token_billing' => 'Save card details',
'token_billing_secure' => 'The data is stored securely by :stripe_link', 'token_billing_secure' => 'The data is stored securely by :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Contact Information', 'contact_information' => 'Contact Information',
'256_encryption' => '256-Bit Encryption', '256_encryption' => '256-Bit Encryption',

View File

@ -489,11 +489,11 @@ return array(
'token_billing_3' => 'Opt-out - el checkbox es mostrado y seleccionado', 'token_billing_3' => 'Opt-out - el checkbox es mostrado y seleccionado',
'token_billing_4' => 'Siempre', 'token_billing_4' => 'Siempre',
'token_billing_checkbox' => 'Almacenar detalles de la tarjeta de crédito', 'token_billing_checkbox' => 'Almacenar detalles de la tarjeta de crédito',
'view_in_stripe' => 'Ver en Stripe', 'view_in_gateway' => 'Ver en :gateway',
'use_card_on_file' => 'Usar la tarjeta en el archivo', 'use_card_on_file' => 'Usar la tarjeta en el archivo',
'edit_payment_details' => 'Editar detalles del pago', 'edit_payment_details' => 'Editar detalles del pago',
'token_billing' => 'Guardar detalles de la tarjeta', 'token_billing' => 'Guardar detalles de la tarjeta',
'token_billing_secure' => 'La información es almacenada de manera segura por :stripe_link', 'token_billing_secure' => 'La información es almacenada de manera segura por :link',
'support' => 'Soporte', 'support' => 'Soporte',
'contact_information' => 'Información de Contacto', 'contact_information' => 'Información de Contacto',

View File

@ -509,11 +509,11 @@ return array(
'token_billing_3' => 'La casilla Opt-Out se muestra y se selecciona', 'token_billing_3' => 'La casilla Opt-Out se muestra y se selecciona',
'token_billing_4' => 'Siempre', 'token_billing_4' => 'Siempre',
'token_billing_checkbox' => 'Almacenar datos de la tarjeta de crédito', 'token_billing_checkbox' => 'Almacenar datos de la tarjeta de crédito',
'view_in_stripe' => 'Ver en Stripe', 'view_in_gateway' => 'Ver en :gateway',
'use_card_on_file' => 'Usar tarjeta en fichero', //?? 'use_card_on_file' => 'Usar tarjeta en fichero', //??
'edit_payment_details' => 'Editar detalles de pago', 'edit_payment_details' => 'Editar detalles de pago',
'token_billing' => 'Guardar datos de la tarjeta', 'token_billing' => 'Guardar datos de la tarjeta',
'token_billing_secure' => 'Los datos serán almacenados de forma segura por :stripe_link', 'token_billing_secure' => 'Los datos serán almacenados de forma segura por :link',
'support' => 'Soporte', 'support' => 'Soporte',
'contact_information' => 'Información de Contacto', 'contact_information' => 'Información de Contacto',

View File

@ -509,11 +509,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected', 'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Toujours', 'token_billing_4' => 'Toujours',
'token_billing_checkbox' => 'Enregistrer les informations de paiement', 'token_billing_checkbox' => 'Enregistrer les informations de paiement',
'view_in_stripe' => 'Voir sur Stripe', 'view_in_gateway' => 'Voir sur :gateway',
'use_card_on_file' => 'Use card on file', 'use_card_on_file' => 'Use card on file',
'edit_payment_details' => 'Editer les détails de pauement', 'edit_payment_details' => 'Editer les détails de pauement',
'token_billing' => 'Enregister les détails de paiement', 'token_billing' => 'Enregister les détails de paiement',
'token_billing_secure' => 'Les données sont enregistrées de manière sécurisée par :stripe_link', 'token_billing_secure' => 'Les données sont enregistrées de manière sécurisée par :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Information de contact', 'contact_information' => 'Information de contact',

View File

@ -510,11 +510,11 @@ return array(
'token_billing_3' => 'Désengagement - case à cocher affichée avec sélection', 'token_billing_3' => 'Désengagement - case à cocher affichée avec sélection',
'token_billing_4' => 'Toujours', 'token_billing_4' => 'Toujours',
'token_billing_checkbox' => 'Mémoriser les informations de carte de crédit', 'token_billing_checkbox' => 'Mémoriser les informations de carte de crédit',
'view_in_stripe' => 'Visualiser dans Stripe', 'view_in_gateway' => 'Visualiser dans :gateway',
'use_card_on_file' => 'Mémoriser les informations de la carte pour usage ultérieur', 'use_card_on_file' => 'Mémoriser les informations de la carte pour usage ultérieur',
'edit_payment_details' => 'Éditer les informations de paiement', 'edit_payment_details' => 'Éditer les informations de paiement',
'token_billing' => 'Sauvegarder les informations de carte de crédit', 'token_billing' => 'Sauvegarder les informations de carte de crédit',
'token_billing_secure' => 'Les données sont mémorisées de façon sécuritaire avec :stripe_link', 'token_billing_secure' => 'Les données sont mémorisées de façon sécuritaire avec :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Contact', 'contact_information' => 'Contact',

View File

@ -512,11 +512,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected', 'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Sempre', 'token_billing_4' => 'Sempre',
'token_billing_checkbox' => 'Salva dettagli carta di credito', 'token_billing_checkbox' => 'Salva dettagli carta di credito',
'view_in_stripe' => 'Vedi transazione in Stripe', 'view_in_gateway' => 'Vedi transazione in :gateway',
'use_card_on_file' => 'Carta di credito salvata', 'use_card_on_file' => 'Carta di credito salvata',
'edit_payment_details' => 'Modifica dettagli pagamento', 'edit_payment_details' => 'Modifica dettagli pagamento',
'token_billing' => 'Salva carta di credito', 'token_billing' => 'Salva carta di credito',
'token_billing_secure' => 'I dati sono memorizzati su piattaforma sicura mediante :stripe_link', 'token_billing_secure' => 'I dati sono memorizzati su piattaforma sicura mediante :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Informazioni di contatto', 'contact_information' => 'Informazioni di contatto',

View File

@ -445,11 +445,11 @@ $LANG = array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected', 'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Always', 'token_billing_4' => 'Always',
'token_billing_checkbox' => 'Store credit card details', 'token_billing_checkbox' => 'Store credit card details',
'view_in_stripe' => 'View in Stripe', 'view_in_gateway' => 'View in :gateway',
'use_card_on_file' => 'Use card on file', 'use_card_on_file' => 'Use card on file',
'edit_payment_details' => 'Edit payment details', 'edit_payment_details' => 'Edit payment details',
'token_billing' => 'Save card details', 'token_billing' => 'Save card details',
'token_billing_secure' => 'The data is stored securely by :stripe_link', 'token_billing_secure' => 'The data is stored securely by :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Contact Information', 'contact_information' => 'Contact Information',
'256_encryption' => '256-Bit Encryption', '256_encryption' => '256-Bit Encryption',

View File

@ -520,11 +520,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected', 'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Always', 'token_billing_4' => 'Always',
'token_billing_checkbox' => 'Store credit card details', 'token_billing_checkbox' => 'Store credit card details',
'view_in_stripe' => 'View in Stripe', 'view_in_gateway' => 'View in :gateway',
'use_card_on_file' => 'Use card on file', 'use_card_on_file' => 'Use card on file',
'edit_payment_details' => 'Edit payment details', 'edit_payment_details' => 'Edit payment details',
'token_billing' => 'Save card details', 'token_billing' => 'Save card details',
'token_billing_secure' => 'The data is stored securely by :stripe_link', 'token_billing_secure' => 'The data is stored securely by :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Contact information', 'contact_information' => 'Contact information',

View File

@ -516,11 +516,11 @@ return array(
'token_billing_3' => 'Aktivert - valgboks er vist og valgt', 'token_billing_3' => 'Aktivert - valgboks er vist og valgt',
'token_billing_4' => 'Alltid', 'token_billing_4' => 'Alltid',
'token_billing_checkbox' => 'Lagre bankkort detaljer', 'token_billing_checkbox' => 'Lagre bankkort detaljer',
'view_in_stripe' => 'Vis i Stripe', 'view_in_gateway' => 'Vis i :gateway',
'use_card_on_file' => 'Bruk lagret kort', 'use_card_on_file' => 'Bruk lagret kort',
'edit_payment_details' => 'Rediger betalings detaljer', 'edit_payment_details' => 'Rediger betalings detaljer',
'token_billing' => 'Lagre kort detaljer', 'token_billing' => 'Lagre kort detaljer',
'token_billing_secure' => 'Dataene er trygt lagret av :stripe_link', 'token_billing_secure' => 'Dataene er trygt lagret av :link',
'support' => 'Brukerstøtte', 'support' => 'Brukerstøtte',
'contact_information' => 'Kontaktinformasjon', 'contact_information' => 'Kontaktinformasjon',

View File

@ -512,11 +512,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is getoond en geselecteerd', 'token_billing_3' => 'Opt-out - checkbox is getoond en geselecteerd',
'token_billing_4' => 'Altijd', 'token_billing_4' => 'Altijd',
'token_billing_checkbox' => 'Sla carditcard gegevens op', 'token_billing_checkbox' => 'Sla carditcard gegevens op',
'view_in_stripe' => 'In Stripe bekijken', 'view_in_gateway' => 'In :gateway bekijken',
'use_card_on_file' => 'Gebruik opgeslagen kaart', 'use_card_on_file' => 'Gebruik opgeslagen kaart',
'edit_payment_details' => 'Betalingsdetails aanpassen', 'edit_payment_details' => 'Betalingsdetails aanpassen',
'token_billing' => 'Kaartgegevens opslaan', 'token_billing' => 'Kaartgegevens opslaan',
'token_billing_secure' => 'Kaartgegevens worden veilig opgeslagen door :stripe_link', 'token_billing_secure' => 'Kaartgegevens worden veilig opgeslagen door :link',
'support' => 'Ondersteuning', 'support' => 'Ondersteuning',
'contact_information' => 'Contact informatie', 'contact_information' => 'Contact informatie',

View File

@ -514,7 +514,7 @@ return array(
'use_card_on_file' => 'Usar cartão no arquivo', 'use_card_on_file' => 'Usar cartão no arquivo',
'edit_payment_details' => 'Editar detalhes do pagamento', 'edit_payment_details' => 'Editar detalhes do pagamento',
'token_billing' => 'Salvar detalhes do cartão', 'token_billing' => 'Salvar detalhes do cartão',
'token_billing_secure' => 'Dados armazenados com seguração por :stripe_link', 'token_billing_secure' => 'Dados armazenados com seguração por :link',
'support' => 'Suporte', 'support' => 'Suporte',
'contact_information' => 'Informações de Contato', 'contact_information' => 'Informações de Contato',

View File

@ -515,11 +515,11 @@ return array(
'token_billing_3' => 'Opt-out - Checkbox visas och är förvald', 'token_billing_3' => 'Opt-out - Checkbox visas och är förvald',
'token_billing_4' => 'alltid', 'token_billing_4' => 'alltid',
'token_billing_checkbox' => 'Spara betalkortsinformation', 'token_billing_checkbox' => 'Spara betalkortsinformation',
'view_in_stripe' => 'Visa i Stripe', 'view_in_gateway' => 'Visa i :gateway',
'use_card_on_file' => 'Använd kort på fil', 'use_card_on_file' => 'Använd kort på fil',
'edit_payment_details' => 'Ändra betalningsdetaljer', 'edit_payment_details' => 'Ändra betalningsdetaljer',
'token_billing' => 'Spara kortinformation', 'token_billing' => 'Spara kortinformation',
'token_billing_secure' => 'Data sparas säkert med :stripe_link', 'token_billing_secure' => 'Data sparas säkert med :link',
'support' => 'Support', 'support' => 'Support',
'contact_information' => 'Kontaktinformation', 'contact_information' => 'Kontaktinformation',

View File

@ -84,7 +84,9 @@
@if ($gateway->id == GATEWAY_STRIPE) @if ($gateway->id == GATEWAY_STRIPE)
{!! Former::text('publishable_key') !!} {!! Former::text('publishable_key') !!}
@endif
@if ($gateway->id == GATEWAY_STRIPE || $gateway->id == GATEWAY_BRAINTREE)
{!! Former::select('token_billing_type_id') {!! Former::select('token_billing_type_id')
->options($tokenBillingOptions) ->options($tokenBillingOptions)
->help(trans('texts.token_billing_help')) !!} ->help(trans('texts.token_billing_help')) !!}

View File

@ -39,7 +39,7 @@
</div> </div>
@if ($gatewayLink) @if ($gatewayLink)
{!! Button::normal(trans('texts.view_in_stripe'))->asLinkTo($gatewayLink)->withAttributes(['target' => '_blank']) !!} {!! Button::normal(trans('texts.view_in_gateway', ['gateway'=>$gateway->gateway->name]))->asLinkTo($gatewayLink)->withAttributes(['target' => '_blank']) !!}
@endif @endif
@if ($client->trashed()) @if ($client->trashed())

View File

@ -2,8 +2,63 @@
@section('head') @section('head')
@parent @parent
@if (!empty($braintreeClientToken))
<script type="text/javascript" src="https://js.braintreegateway.com/js/braintree-2.23.0.min.js"></script>
<script type="text/javascript" >
$(function() {
braintree.setup("{{ $braintreeClientToken }}", "custom", {
id: "payment-form",
hostedFields: {
number: {
selector: "#card_number",
placeholder: "{{ trans('texts.card_number') }}"
},
cvv: {
selector: "#cvv",
placeholder: "{{ trans('texts.cvv') }}"
},
expirationMonth: {
selector: "#expiration_month",
placeholder: "{{ trans('texts.expiration_month') }}"
},
expirationYear: {
selector: "#expiration_year",
placeholder: "{{ trans('texts.expiration_year') }}"
},
styles: {
'input': {
'font-family': {!! json_encode(Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_stack']) !!},
'font-weight': "{{ Utils::getFromCache($account->getBodyFontId(), 'fonts')['css_weight'] }}",
'font-size': '16px'
}
}
},
onError: function(e) {
// Show the errors on the form
if (e.details && e.details.invalidFieldKeys.length) {
var invalidField = e.details.invalidFieldKeys[0];
@if ($accountGateway->getPublishableStripeKey()) if (invalidField == 'number') {
$('#js-error-message').html('{{ trans('texts.invalid_card_number') }}').fadeIn();
}
else if (invalidField == 'expirationDate' || invalidField == 'expirationYear' || invalidField == 'expirationMonth') {
$('#js-error-message').html('{{ trans('texts.invalid_expiry') }}').fadeIn();
}
else if (invalidField == 'cvv') {
$('#js-error-message').html('{{ trans('texts.invalid_cvv') }}').fadeIn();
}
}
else {
$('#js-error-message').html(e.message).fadeIn();
}
}
});
$('.payment-form').submit(function(event) {
$('#js-error-message').hide();
});
});
</script>
@elseif ($accountGateway->getPublishableStripeKey())
<script type="text/javascript" src="https://js.stripe.com/v2/"></script> <script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript"> <script type="text/javascript">
Stripe.setPublishableKey('{{ $accountGateway->getPublishableStripeKey() }}'); Stripe.setPublishableKey('{{ $accountGateway->getPublishableStripeKey() }}');
@ -92,6 +147,7 @@
{!! Former::vertical_open($url) {!! Former::vertical_open($url)
->autocomplete('on') ->autocomplete('on')
->addClass('payment-form') ->addClass('payment-form')
->id('payment-form')
->rules(array( ->rules(array(
'first_name' => 'required', 'first_name' => 'required',
'last_name' => 'required', 'last_name' => 'required',
@ -238,22 +294,33 @@
<h3>{{ trans('texts.billing_method') }}</h3> <h3>{{ trans('texts.billing_method') }}</h3>
<div class="row"> <div class="row">
<div class="col-md-9"> <div class="col-md-9">
@if (!empty($braintreeClientToken))
<div id="card_number" class="braintree-hosted form-control"></div>
@else
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'card_number') {!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'card_number')
->id('card_number') ->id('card_number')
->placeholder(trans('texts.card_number')) ->placeholder(trans('texts.card_number'))
->autocomplete('cc-number') ->autocomplete('cc-number')
->label('') !!} ->label('') !!}
@endif
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
@if (!empty($braintreeClientToken))
<div id="cvv" class="braintree-hosted form-control"></div>
@else
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv') {!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv')
->id('cvv') ->id('cvv')
->placeholder(trans('texts.cvv')) ->placeholder(trans('texts.cvv'))
->autocomplete('off') ->autocomplete('off')
->label('') !!} ->label('') !!}
@endif
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
@if (!empty($braintreeClientToken))
<div id="expiration_month" class="braintree-hosted form-control"></div>
@else
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_month') {!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_month')
->id('expiration_month') ->id('expiration_month')
->autocomplete('cc-exp-month') ->autocomplete('cc-exp-month')
@ -271,8 +338,12 @@
->addOption('11 - November', '11') ->addOption('11 - November', '11')
->addOption('12 - December', '12')->label('') ->addOption('12 - December', '12')->label('')
!!} !!}
@endif
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
@if (!empty($braintreeClientToken))
<div id="expiration_year" class="braintree-hosted form-control"></div>
@else
{!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_year') {!! Former::select($accountGateway->getPublishableStripeKey() ? '' : 'expiration_year')
->id('expiration_year') ->id('expiration_year')
->autocomplete('cc-exp-year') ->autocomplete('cc-exp-year')
@ -289,16 +360,23 @@
->addOption('2025', '2025') ->addOption('2025', '2025')
->addOption('2026', '2026')->label('') ->addOption('2026', '2026')->label('')
!!} !!}
@endif
</div> </div>
</div> </div>
<div class="row" style="padding-top:18px"> <div class="row" style="padding-top:18px">
<div class="col-md-5"> <div class="col-md-5">
@if ($client && $account->showTokenCheckbox()) @if ($client && $account->showTokenCheckbox($storageGateway))
<input id="token_billing" type="checkbox" name="token_billing" {{ $account->selectTokenCheckbox() ? 'CHECKED' : '' }} value="1" style="margin-left:0px; vertical-align:top"> <input id="token_billing" type="checkbox" name="token_billing" {{ $account->selectTokenCheckbox() ? 'CHECKED' : '' }} value="1" style="margin-left:0px; vertical-align:top">
<label for="token_billing" class="checkbox" style="display: inline;">{{ trans('texts.token_billing') }}</label> <label for="token_billing" class="checkbox" style="display: inline;">{{ trans('texts.token_billing') }}</label>
<span class="help-block" style="font-size:15px">{!! trans('texts.token_billing_secure', ['stripe_link' => link_to('https://stripe.com/', 'Stripe.com', ['target' => '_blank'])]) !!}</span> <span class="help-block" style="font-size:15px">
@if ($storageGateway == GATEWAY_STRIPE)
{!! trans('texts.token_billing_secure', ['link' => link_to('https://stripe.com/', 'Stripe.com', ['target' => '_blank'])]) !!}
@elseif ($storageGateway == GATEWAY_BRAINTREE)
{!! trans('texts.token_billing_secure', ['link' => link_to('https://www.braintreepayments.com/', 'Braintree', ['target' => '_blank'])]) !!}
@endif
</span>
@endif @endif
</div> </div>

View File

@ -12,9 +12,14 @@ body {
.container input[type=text], .container input[type=text],
.container input[type=email], .container input[type=email],
.container select { .container select,
.braintree-hosted {
@if(!empty($account))
{!! $account->getBodyFontCss() !!}
@else
font-weight: 300; font-weight: 300;
font-family: 'Roboto', sans-serif; font-family: 'Roboto', sans-serif;
@endif
width: 100%; width: 100%;
padding: 11px; padding: 11px;
color: #8c8c8c; color: #8c8c8c;
@ -26,6 +31,12 @@ body {
font-weight: 400; font-weight: 400;
} }
.form-control.braintree-hosted-fields-focused{
border-color: #66afe9;
outline: 0;
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
div.col-md-3, div.col-md-3,
div.col-md-5, div.col-md-5,
div.col-md-6, div.col-md-6,