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,
'hasQuotes' => Invoice::scope()->where('is_quote', '=', true)->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);

View File

@ -200,6 +200,10 @@ class PaymentController extends BaseController
'showAddress' => $accountGateway->show_address,
];
if ($gateway->id = GATEWAY_BRAINTREE) {
$data['braintreeClientToken'] = $this->paymentService->getBraintreeClientToken($account);
}
return View::make('payments.payment', $data);
}
@ -377,7 +381,7 @@ class PaymentController extends BaseController
'last_name' => 'required',
];
if ( ! Input::get('stripeToken')) {
if ( ! Input::get('stripeToken') && ! Input::get('payment_method_nonce')) {
$rules = array_merge(
$rules,
[
@ -451,6 +455,28 @@ class PaymentController extends BaseController
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();

View File

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

View File

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

View File

@ -1199,9 +1199,9 @@ class Account extends Eloquent
return false;
}
public function showTokenCheckbox()
public function showTokenCheckbox(&$storage_gateway = null)
{
if (!$this->isGatewayConfigured(GATEWAY_STRIPE)) {
if (!$this->getTokenGatewayId()) {
return false;
}
@ -1209,6 +1209,25 @@ class Account extends Eloquent
|| $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()
{
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');
if (!count($this->account->account_gateways)) {
return false;
}
$accountGateway = $this->account->getTokenGateway();
$accountGateway = $this->account->getGatewayConfig(GATEWAY_STRIPE);
if (!$accountGateway) {
return false;
}
@ -274,10 +273,22 @@ class Client extends EntityModel
return $token ? $token->token : false;
}
public function getGatewayLink()
public function getGatewayLink(&$accountGateway = null)
{
$token = $this->getGatewayToken();
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false;
$token = $this->getGatewayToken($accountGateway);
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()

View File

@ -157,15 +157,26 @@ class PaymentService extends BaseService
public function createToken($gateway, $details, $accountGateway, $client, $contactId, &$customerReference = null)
{
$tokenResponse = $gateway->createCard($details)->send();
$cardReference = $tokenResponse->getCardReference();
$customerReference = $tokenResponse->getCustomerReference();
if ($customerReference == $cardReference) {
// This customer was just created; find the card
$data = $tokenResponse->getData();
if(!empty($data['default_source'])) {
$cardReference = $data['default_source'];
if ($accountGateway->gateway->id == GATEWAY_STRIPE) {
$tokenResponse = $gateway->createCard($details)->send();
$cardReference = $tokenResponse->getCardReference();
$customerReference = $tokenResponse->getCustomerReference();
if ($customerReference == $cardReference) {
// This customer was just created; find the card
$data = $tokenResponse->getData();
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;
}
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)
{
$invoice = $invitation->invoice;
@ -228,7 +251,7 @@ class PaymentService extends BaseService
$payment->transaction_reference = $ref;
$payment->payment_date = date_create()->format('Y-m-d');
if (!empty($paymentDetails['card'])) {
if (!empty($paymentDetails['card'])) {
$card = $paymentDetails['card'];
$payment->last4 = substr($card->number, -4);
$year = $card->expiryYear;
@ -255,7 +278,7 @@ class PaymentService extends BaseService
'MasterCard' => CARD_MASTERCARD,
'Discover' => CARD_DISCOVER,
'JCB' => CARD_JCB,
'Diners Club' => CARD_DINERS_CLUB
'Diners Club' => CARD_DINERS_CLUB,
);
if (!empty($stripe_card_types[$card['brand']])) {
@ -264,6 +287,31 @@ class PaymentService extends BaseService
$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) {
@ -363,7 +411,7 @@ class PaymentService extends BaseService
$client = $invoice->client;
$account = $invoice->account;
$invitation = $invoice->invitations->first();
$accountGateway = $account->getGatewayConfig(GATEWAY_STRIPE);
$accountGateway = $account->getTokenGateway();
$token = $client->getGatewayToken();
if (!$invitation || !$accountGateway || !$token) {
@ -375,12 +423,21 @@ class PaymentService extends BaseService
$details = $this->getPaymentDetails($invitation, $accountGateway);
$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
$response = $gateway->purchase($details)->send();
if ($response->isSuccessful()) {
$ref = $response->getTransactionReference();
return $this->createPayment($invitation, $accountGateway, $ref, $details, $response);
return $this->createPayment($invitation, $accountGateway, $ref, null, $details, $response);
} else {
return false;
}

View File

@ -72,7 +72,8 @@
"asgrim/ofxparser": "^1.1",
"league/flysystem-aws-s3-v3": "~1.0",
"league/flysystem-rackspace": "~1.0",
"barracudanetworks/archivestream-php": "^1.0"
"barracudanetworks/archivestream-php": "^1.0",
"omnipay/braintree": "~2.0@dev"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
@ -122,4 +123,4 @@
"config": {
"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",
"This file is @generated automatically"
],
"hash": "607b25b09aee82ac769bd942fac91ba6",
"content-hash": "122f3f59beb2286159145d219dbcbc90",
"hash": "e2b43d6bd5e87dfb9b3be07e89a2bd9f",
"content-hash": "480134957ff37fd0f46b5d90909da660",
"packages": [
{
"name": "agmscode/omnipay-agms",
@ -558,6 +558,53 @@
],
"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",
"version": "v2.0.0",
@ -2338,7 +2385,7 @@
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/e368d262887dbb2fdfaf710880571ede51e9c0e6",
"url": "https://api.github.com/repos/Intervention/image/zipball/22088b04728a039bd1fc32f7e79a89a118b78698",
"reference": "e368d262887dbb2fdfaf710880571ede51e9c0e6",
"shasum": ""
},
@ -4277,6 +4324,69 @@
],
"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",
"version": "v2.0.1",
@ -9894,7 +10004,8 @@
"meebio/omnipay-secure-trading": 20,
"labs7in0/omnipay-wechat": 20,
"laracasts/presenter": 20,
"jlapp/swaggervel": 20
"jlapp/swaggervel": 20,
"omnipay/braintree": 20
},
"prefer-stable": false,
"prefer-lowest": false,

View File

@ -48,6 +48,7 @@ class PaymentLibrariesSeeder extends Seeder
['name' => 'SecPay', 'provider' => 'SecPay', 'payment_library_id' => 1],
['name' => 'WeChat Express', 'provider' => 'WeChat_Express', 'payment_library_id' => 1],
['name' => 'WePay', 'provider' => 'WePay', 'payment_library_id' => 1],
['name' => 'Braintree', 'provider' => 'Braintree', 'payment_library_id' => 1],
];
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.
|
*/
require __DIR__.'/../bootstrap/autoload.php';
/*

View File

@ -516,11 +516,11 @@ return array(
'token_billing_3' => 'Fravalg - checkboks er vist og valgt',
'token_billing_4' => 'Altid',
'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',
'edit_payment_details' => 'Redigér betalings 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',
'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_4' => 'Immer',
'token_billing_checkbox' => 'Kreditkarteninformationen speichern',
'view_in_stripe' => 'Auf Stripe anzeigen',
'view_in_gateway' => 'Auf :gateway anzeigen',
'use_card_on_file' => 'Verwende gespeicherte Kreditkarte',
'edit_payment_details' => 'Zahlungsdetails bearbeiten',
'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',
'contact_information' => 'Kontakt-Informationen',

View File

@ -444,11 +444,11 @@ $LANG = array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Always',
'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',
'edit_payment_details' => 'Edit payment 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',
'contact_information' => 'Contact Information',
'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_4' => 'Siempre',
'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',
'edit_payment_details' => 'Editar detalles del pago',
'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',
'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_4' => 'Siempre',
'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', //??
'edit_payment_details' => 'Editar detalles de pago',
'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',
'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_4' => 'Toujours',
'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',
'edit_payment_details' => 'Editer les détails de pauement',
'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',
'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_4' => 'Toujours',
'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',
'edit_payment_details' => 'Éditer les informations de paiement',
'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',
'contact_information' => 'Contact',

View File

@ -512,11 +512,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is shown and selected',
'token_billing_4' => 'Sempre',
'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',
'edit_payment_details' => 'Modifica dettagli pagamento',
'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',
'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_4' => 'Always',
'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',
'edit_payment_details' => 'Edit payment 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',
'contact_information' => 'Contact Information',
'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_4' => 'Always',
'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',
'edit_payment_details' => 'Edit payment 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',
'contact_information' => 'Contact information',

View File

@ -516,11 +516,11 @@ return array(
'token_billing_3' => 'Aktivert - valgboks er vist og valgt',
'token_billing_4' => 'Alltid',
'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',
'edit_payment_details' => 'Rediger betalings 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',
'contact_information' => 'Kontaktinformasjon',

View File

@ -512,11 +512,11 @@ return array(
'token_billing_3' => 'Opt-out - checkbox is getoond en geselecteerd',
'token_billing_4' => 'Altijd',
'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',
'edit_payment_details' => 'Betalingsdetails aanpassen',
'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',
'contact_information' => 'Contact informatie',

View File

@ -514,7 +514,7 @@ return array(
'use_card_on_file' => 'Usar cartão no arquivo',
'edit_payment_details' => 'Editar detalhes do pagamento',
'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',
'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_4' => 'alltid',
'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',
'edit_payment_details' => 'Ändra betalningsdetaljer',
'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',
'contact_information' => 'Kontaktinformation',

View File

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

View File

@ -39,7 +39,7 @@
</div>
@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
@if ($client->trashed())

View File

@ -2,8 +2,63 @@
@section('head')
@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">
Stripe.setPublishableKey('{{ $accountGateway->getPublishableStripeKey() }}');
@ -92,6 +147,7 @@
{!! Former::vertical_open($url)
->autocomplete('on')
->addClass('payment-form')
->id('payment-form')
->rules(array(
'first_name' => 'required',
'last_name' => 'required',
@ -238,22 +294,33 @@
<h3>{{ trans('texts.billing_method') }}</h3>
<div class="row">
<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')
->id('card_number')
->placeholder(trans('texts.card_number'))
->autocomplete('cc-number')
->label('') !!}
@endif
</div>
<div class="col-md-3">
@if (!empty($braintreeClientToken))
<div id="cvv" class="braintree-hosted form-control"></div>
@else
{!! Former::text($accountGateway->getPublishableStripeKey() ? '' : 'cvv')
->id('cvv')
->placeholder(trans('texts.cvv'))
->autocomplete('off')
->label('') !!}
@endif
</div>
</div>
<div class="row">
<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')
->id('expiration_month')
->autocomplete('cc-exp-month')
@ -271,8 +338,12 @@
->addOption('11 - November', '11')
->addOption('12 - December', '12')->label('')
!!}
@endif
</div>
<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')
->id('expiration_year')
->autocomplete('cc-exp-year')
@ -289,16 +360,23 @@
->addOption('2025', '2025')
->addOption('2026', '2026')->label('')
!!}
@endif
</div>
</div>
<div class="row" style="padding-top:18px">
<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">
<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
</div>

View File

@ -12,9 +12,14 @@ body {
.container input[type=text],
.container input[type=email],
.container select {
.container select,
.braintree-hosted {
@if(!empty($account))
{!! $account->getBodyFontCss() !!}
@else
font-weight: 300;
font-family: 'Roboto', sans-serif;
@endif
width: 100%;
padding: 11px;
color: #8c8c8c;
@ -26,6 +31,12 @@ body {
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-5,
div.col-md-6,