mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-07 19:04:41 -04:00
Added support for Stripe token billing
This commit is contained in:
parent
fbf7c235e8
commit
7f27abace2
@ -184,6 +184,11 @@ class AccountController extends \BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$tokenBillingOptions = [];
|
||||||
|
for ($i=1; $i<=4; $i++) {
|
||||||
|
$tokenBillingOptions[$i] = trans("texts.token_billing_{$i}");
|
||||||
|
}
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'account' => $account,
|
'account' => $account,
|
||||||
'accountGateway' => $accountGateway,
|
'accountGateway' => $accountGateway,
|
||||||
@ -195,7 +200,8 @@ class AccountController extends \BaseController
|
|||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get(),
|
->get(),
|
||||||
'recommendedGateways' => $recommendedGatewayArray,
|
'recommendedGateways' => $recommendedGatewayArray,
|
||||||
'creditCardTypes' => $creditCards,
|
'creditCardTypes' => $creditCards,
|
||||||
|
'tokenBillingOptions' => $tokenBillingOptions,
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('accounts.payments', $data);
|
return View::make('accounts.payments', $data);
|
||||||
@ -663,10 +669,22 @@ class AccountController extends \BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($isMasked && count($account->account_gateways)) {
|
// check if a gateway is already configured
|
||||||
|
$currentGateway = false;
|
||||||
|
if (count($account->account_gateways)) {
|
||||||
$currentGateway = $account->account_gateways[0];
|
$currentGateway = $account->account_gateways[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the values haven't changed don't update the config
|
||||||
|
if ($isMasked && $currentGateway) {
|
||||||
$currentGateway->accepted_credit_cards = $cardCount;
|
$currentGateway->accepted_credit_cards = $cardCount;
|
||||||
$currentGateway->save();
|
$currentGateway->save();
|
||||||
|
// if there's an existing config for this gateway update it
|
||||||
|
} elseif (!$isMasked && $currentGateway && $currentGateway->gateway_id == $gatewayId) {
|
||||||
|
$currentGateway->accepted_credit_cards = $cardCount;
|
||||||
|
$currentGateway->config = json_encode($config);
|
||||||
|
$currentGateway->save();
|
||||||
|
// otherwise, create a new gateway config
|
||||||
} else {
|
} else {
|
||||||
$accountGateway->config = json_encode($config);
|
$accountGateway->config = json_encode($config);
|
||||||
$accountGateway->accepted_credit_cards = $cardCount;
|
$accountGateway->accepted_credit_cards = $cardCount;
|
||||||
@ -675,6 +693,11 @@ class AccountController extends \BaseController
|
|||||||
$account->account_gateways()->save($accountGateway);
|
$account->account_gateways()->save($accountGateway);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Input::get('token_billing_type_id')) {
|
||||||
|
$account->token_billing_type_id = Input::get('token_billing_type_id');
|
||||||
|
$account->save();
|
||||||
|
}
|
||||||
|
|
||||||
Session::flash('message', trans('texts.updated_settings'));
|
Session::flash('message', trans('texts.updated_settings'));
|
||||||
} else {
|
} else {
|
||||||
Session::flash('error', trans('validation.required', ['attribute' => 'gateway']));
|
Session::flash('error', trans('validation.required', ['attribute' => 'gateway']));
|
||||||
|
@ -106,6 +106,7 @@ class ClientController extends \BaseController
|
|||||||
'credit' => $client->getTotalCredit(),
|
'credit' => $client->getTotalCredit(),
|
||||||
'title' => trans('texts.view_client'),
|
'title' => trans('texts.view_client'),
|
||||||
'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0,
|
'hasRecurringInvoices' => Invoice::scope()->where('is_recurring', '=', true)->whereClientId($client->id)->count() > 0,
|
||||||
|
'gatewayLink' => $client->getGatewayLink(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return View::make('clients.show', $data);
|
return View::make('clients.show', $data);
|
||||||
|
@ -177,6 +177,7 @@ class InvoiceController extends \BaseController
|
|||||||
'invitation' => $invitation,
|
'invitation' => $invitation,
|
||||||
'invoiceLabels' => $client->account->getInvoiceLabels(),
|
'invoiceLabels' => $client->account->getInvoiceLabels(),
|
||||||
'contact' => $contact,
|
'contact' => $contact,
|
||||||
|
'hasToken' => $client->getGatewayToken()
|
||||||
);
|
);
|
||||||
|
|
||||||
return View::make('invoices.view', $data);
|
return View::make('invoices.view', $data);
|
||||||
|
@ -287,14 +287,16 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
public function show_payment($invitationKey)
|
public function show_payment($invitationKey)
|
||||||
{
|
{
|
||||||
|
// Handle token billing
|
||||||
|
if (Input::get('use_token') == 'true') {
|
||||||
|
return self::do_payment($invitationKey, false, true);
|
||||||
|
}
|
||||||
// For PayPal Express we redirect straight to their site
|
// For PayPal Express we redirect straight to their site
|
||||||
$invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
$invitation = Invitation::with('invoice.client.account', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
$account = $invitation->invoice->client->account;
|
$account = $invitation->invoice->client->account;
|
||||||
|
|
||||||
if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) {
|
if ($account->isGatewayConfigured(GATEWAY_PAYPAL_EXPRESS)) {
|
||||||
if (Session::has('error')) {
|
if (Session::has('error')) {
|
||||||
Session::reflash();
|
Session::reflash();
|
||||||
|
|
||||||
return Redirect::to('view/'.$invitationKey);
|
return Redirect::to('view/'.$invitationKey);
|
||||||
} else {
|
} else {
|
||||||
return self::do_payment($invitationKey, false);
|
return self::do_payment($invitationKey, false);
|
||||||
@ -321,6 +323,7 @@ class PaymentController extends \BaseController
|
|||||||
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
|
'acceptedCreditCardTypes' => $acceptedCreditCardTypes,
|
||||||
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
'countries' => Country::remember(DEFAULT_QUERY_CACHE)->orderBy('name')->get(),
|
||||||
'currencyId' => $client->currency_id,
|
'currencyId' => $client->currency_id,
|
||||||
|
'account' => $client->account
|
||||||
];
|
];
|
||||||
|
|
||||||
return View::make('payments.payment', $data);
|
return View::make('payments.payment', $data);
|
||||||
@ -486,7 +489,7 @@ class PaymentController extends \BaseController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function do_payment($invitationKey, $onSite = true)
|
public function do_payment($invitationKey, $onSite = true, $useToken = false)
|
||||||
{
|
{
|
||||||
$rules = array(
|
$rules = array(
|
||||||
'first_name' => 'required',
|
'first_name' => 'required',
|
||||||
@ -512,11 +515,12 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
$invitation = Invitation::with('invoice.invoice_items', 'invoice.client.currency', 'invoice.client.account.account_gateways.gateway')->where('invitation_key', '=', $invitationKey)->firstOrFail();
|
||||||
$invoice = $invitation->invoice;
|
$invoice = $invitation->invoice;
|
||||||
$accountGateway = $invoice->client->account->account_gateways[0];
|
$client = $invoice->client;
|
||||||
|
$account = $client->account;
|
||||||
|
$accountGateway = $account->account_gateways[0];
|
||||||
$paymentLibrary = $accountGateway->gateway->paymentlibrary;
|
$paymentLibrary = $accountGateway->gateway->paymentlibrary;
|
||||||
|
|
||||||
if ($onSite) {
|
if ($onSite) {
|
||||||
$client = $invoice->client;
|
|
||||||
$client->address1 = trim(Input::get('address1'));
|
$client->address1 = trim(Input::get('address1'));
|
||||||
$client->address2 = trim(Input::get('address2'));
|
$client->address2 = trim(Input::get('address2'));
|
||||||
$client->city = trim(Input::get('city'));
|
$client->city = trim(Input::get('city'));
|
||||||
@ -528,7 +532,32 @@ class PaymentController extends \BaseController
|
|||||||
try {
|
try {
|
||||||
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
|
if ($paymentLibrary->id == PAYMENT_LIBRARY_OMNIPAY) {
|
||||||
$gateway = self::createGateway($accountGateway);
|
$gateway = self::createGateway($accountGateway);
|
||||||
$details = self::getPaymentDetails($invoice, Input::all());
|
$details = self::getPaymentDetails($invoice, $useToken ? false : Input::all());
|
||||||
|
|
||||||
|
if ($accountGateway->gateway_id == GATEWAY_STRIPE) {
|
||||||
|
if ($useToken) {
|
||||||
|
$details['cardReference'] = $client->getGatewayToken();
|
||||||
|
} elseif ($account->token_billing_type_id == TOKEN_BILLING_ALWAYS || Input::get('token_billing')) {
|
||||||
|
$tokenResponse = $gateway->createCard($details)->send();
|
||||||
|
$cardReference = $tokenResponse->getCardReference();
|
||||||
|
$details['cardReference'] = $cardReference;
|
||||||
|
|
||||||
|
$token = AccountGatewayToken::where('client_id', '=', $client->id)
|
||||||
|
->where('account_gateway_id', '=', $accountGateway->id)->first();
|
||||||
|
|
||||||
|
if (!$token) {
|
||||||
|
$token = new AccountGatewayToken();
|
||||||
|
$token->account_id = $account->id;
|
||||||
|
$token->contact_id = $invitation->contact_id;
|
||||||
|
$token->account_gateway_id = $accountGateway->id;
|
||||||
|
$token->client_id = $client->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$token->token = $cardReference;
|
||||||
|
$token->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$response = $gateway->purchase($details)->send();
|
$response = $gateway->purchase($details)->send();
|
||||||
$ref = $response->getTransactionReference();
|
$ref = $response->getTransactionReference();
|
||||||
|
|
||||||
@ -541,7 +570,6 @@ class PaymentController extends \BaseController
|
|||||||
|
|
||||||
if ($response->isSuccessful()) {
|
if ($response->isSuccessful()) {
|
||||||
$payment = self::createPayment($invitation, $ref);
|
$payment = self::createPayment($invitation, $ref);
|
||||||
|
|
||||||
Session::flash('message', trans('texts.applied_payment'));
|
Session::flash('message', trans('texts.applied_payment'));
|
||||||
|
|
||||||
return Redirect::to('view/'.$payment->invitation->invitation_key);
|
return Redirect::to('view/'.$payment->invitation->invitation_key);
|
||||||
@ -693,12 +721,14 @@ class PaymentController extends \BaseController
|
|||||||
->withInput();
|
->withInput();
|
||||||
} else {
|
} else {
|
||||||
$this->paymentRepo->save($publicId, Input::all());
|
$this->paymentRepo->save($publicId, Input::all());
|
||||||
|
|
||||||
if ($publicId) {
|
if ($publicId) {
|
||||||
Session::flash('message', trans('texts.updated_payment'));
|
Session::flash('message', trans('texts.updated_payment'));
|
||||||
|
|
||||||
return Redirect::to('payments/');
|
return Redirect::to('payments/');
|
||||||
} else {
|
} else {
|
||||||
Session::flash('message', trans('texts.created_payment'));
|
Session::flash('message', trans('texts.created_payment'));
|
||||||
|
|
||||||
return Redirect::to('clients/'.Input::get('client'));
|
return Redirect::to('clients/'.Input::get('client'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class SupportTokenBilling extends Migration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->smallInteger('token_billing_type_id')->default(TOKEN_BILLING_OPT_IN);
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::create('account_gateway_tokens', function($table)
|
||||||
|
{
|
||||||
|
$table->increments('id');
|
||||||
|
$table->unsignedInteger('account_id');
|
||||||
|
$table->unsignedInteger('contact_id');
|
||||||
|
$table->unsignedInteger('account_gateway_id');
|
||||||
|
$table->unsignedInteger('client_id');
|
||||||
|
$table->string('token');
|
||||||
|
|
||||||
|
$table->timestamps();
|
||||||
|
$table->softDeletes();
|
||||||
|
|
||||||
|
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
|
||||||
|
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
|
||||||
|
$table->foreign('account_gateway_id')->references('id')->on('account_gateways')->onDelete('cascade');
|
||||||
|
$table->foreign('client_id')->references('id')->on('clients')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
|
||||||
|
DB::table('accounts')->update(['token_billing_type_id' => TOKEN_BILLING_OPT_IN]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('accounts', function($table)
|
||||||
|
{
|
||||||
|
$table->dropColumn('token_billing_type_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::drop('account_gateway_tokens');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -512,4 +512,17 @@ return array(
|
|||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -500,6 +500,19 @@ return array(
|
|||||||
'payment_email' => 'Zahlungsmail',
|
'payment_email' => 'Zahlungsmail',
|
||||||
'quote_email' => 'Angebotsmail',
|
'quote_email' => 'Angebotsmail',
|
||||||
'reset_all' => 'Alle zurücksetzen',
|
'reset_all' => 'Alle zurücksetzen',
|
||||||
|
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -510,4 +510,18 @@ return array(
|
|||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -482,4 +482,17 @@ return array(
|
|||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
@ -502,5 +502,18 @@ return array(
|
|||||||
'quote_email' => 'Quote Email',
|
'quote_email' => 'Quote Email',
|
||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
@ -504,5 +504,18 @@ return array(
|
|||||||
'quote_email' => 'Quote Email',
|
'quote_email' => 'Quote Email',
|
||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -512,6 +512,19 @@ return array(
|
|||||||
'quote_email' => 'Quote Email',
|
'quote_email' => 'Quote Email',
|
||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -511,5 +511,18 @@ return array(
|
|||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
@ -505,6 +505,19 @@ return array(
|
|||||||
'quote_email' => 'Quote Email',
|
'quote_email' => 'Quote Email',
|
||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
@ -492,6 +492,19 @@ return array(
|
|||||||
'quote_email' => 'Quote Email',
|
'quote_email' => 'Quote Email',
|
||||||
'reset_all' => 'Reset All',
|
'reset_all' => 'Reset All',
|
||||||
'approve' => 'Approve',
|
'approve' => 'Approve',
|
||||||
|
|
||||||
|
'token_billing_type_id' => 'Token Billing',
|
||||||
|
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
|
||||||
|
'token_billing_1' => 'Disabled',
|
||||||
|
'token_billing_2' => 'Opt-in - checkbox is shown but not selected',
|
||||||
|
'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',
|
||||||
|
'use_card_on_file' => 'Use card on file',
|
||||||
|
'edit_payment_details' => 'Edit payment details',
|
||||||
|
'token_billing' => 'Save card details',
|
||||||
|
'token_billing_secure' => 'All data is stored securely by :stripe_link',
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -334,4 +334,15 @@ class Account extends Eloquent
|
|||||||
return "<p>" . trans('texts.email_signature') . "<br>\$account</p>";
|
return "<p>" . trans('texts.email_signature') . "<br>\$account</p>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showTokenCheckbox()
|
||||||
|
{
|
||||||
|
return $this->token_billing_type_id == TOKEN_BILLING_OPT_IN
|
||||||
|
|| $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function selectTokenCheckbox()
|
||||||
|
{
|
||||||
|
return $this->token_billing_type_id == TOKEN_BILLING_OPT_OUT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
7
app/models/AccountGatewayToken.php
Normal file
7
app/models/AccountGatewayToken.php
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class AccountGatewayToken extends Eloquent
|
||||||
|
{
|
||||||
|
protected $softDelete = true;
|
||||||
|
public $timestamps = true;
|
||||||
|
}
|
@ -219,6 +219,33 @@ class Client extends EntityModel
|
|||||||
return $this->created_at->format('m/d/y h:i a');
|
return $this->created_at->format('m/d/y h:i a');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getGatewayToken()
|
||||||
|
{
|
||||||
|
$this->account->load('account_gateways');
|
||||||
|
|
||||||
|
if (!count($this->account->account_gateways)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$accountGateway = $this->account->account_gateways[0];
|
||||||
|
|
||||||
|
if ($accountGateway->gateway_id != GATEWAY_STRIPE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$token = AccountGatewayToken::where('client_id', '=', $this->id)
|
||||||
|
->where('account_gateway_id', '=', $accountGateway->id)->first();
|
||||||
|
|
||||||
|
return $token ? $token->token : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getGatewayLink()
|
||||||
|
{
|
||||||
|
$token = $this->getGatewayToken();
|
||||||
|
return $token ? "https://dashboard.stripe.com/customers/{$token}" : false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -318,6 +318,11 @@ define('USER_TYPE_SELF_HOST', 'SELF_HOST');
|
|||||||
define('USER_TYPE_CLOUD_HOST', 'CLOUD_HOST');
|
define('USER_TYPE_CLOUD_HOST', 'CLOUD_HOST');
|
||||||
define('NEW_VERSION_AVAILABLE', 'NEW_VERSION_AVAILABLE');
|
define('NEW_VERSION_AVAILABLE', 'NEW_VERSION_AVAILABLE');
|
||||||
|
|
||||||
|
define('TOKEN_BILLING_DISABLED', 1);
|
||||||
|
define('TOKEN_BILLING_OPT_IN', 2);
|
||||||
|
define('TOKEN_BILLING_OPT_OUT', 3);
|
||||||
|
define('TOKEN_BILLING_ALWAYS', 4);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
define('GATEWAY_AMAZON', 30);
|
define('GATEWAY_AMAZON', 30);
|
||||||
define('GATEWAY_BLUEPAY', 31);
|
define('GATEWAY_BLUEPAY', 31);
|
||||||
|
@ -79,14 +79,18 @@
|
|||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
||||||
@if($gateway->getHelp())
|
@if ($gateway->getHelp())
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-lg-4 col-sm-4"></label>
|
<label class="control-label col-lg-4 col-sm-4"></label>
|
||||||
<div class="col-lg-8 col-sm-8">
|
<div class="col-lg-8 col-sm-8 help-block">
|
||||||
{{ $gateway->getHelp() }}
|
{{ $gateway->getHelp() }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
@if ($gateway->id == GATEWAY_STRIPE)
|
||||||
|
{{ Former::select('token_billing_type_id')->options($tokenBillingOptions)->help(trans('texts.token_billing_help')) }}
|
||||||
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endforeach
|
@endforeach
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
{{ Former::text('id')->value($client->public_id) }}
|
{{ Former::text('id')->value($client->public_id) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if ($gatewayLink)
|
||||||
|
{{ Button::link($gatewayLink, trans('texts.view_in_stripe'), ['target' => '_blank']) }}
|
||||||
|
@endif
|
||||||
|
|
||||||
@if ($client->trashed())
|
@if ($client->trashed())
|
||||||
{{ Button::primary(trans('texts.restore_client'), ['onclick' => 'onRestoreClick()']) }}
|
{{ Button::primary(trans('texts.restore_client'), ['onclick' => 'onRestoreClick()']) }}
|
||||||
@else
|
@else
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
var needsRefresh = false;
|
var needsRefresh = false;
|
||||||
|
|
||||||
function refreshPDF() {
|
function refreshPDF() {
|
||||||
PDFJS.disableWorker = true;
|
PDFJS.workerSrc = '{{ asset('js/pdf_viewer.worker.js') }}';
|
||||||
if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChromium))) {
|
if ({{ Auth::check() && Auth::user()->force_pdfjs ? 'false' : 'true' }} && (isFirefox || (isChrome && !isChromium))) {
|
||||||
var string = getPDFString();
|
var string = getPDFString();
|
||||||
if (!string) return;
|
if (!string) return;
|
||||||
|
@ -30,7 +30,14 @@
|
|||||||
@endif
|
@endif
|
||||||
@elseif ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring)
|
@elseif ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring)
|
||||||
{{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
|
{{ Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
|
||||||
{{ Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) }}
|
@if ($hasToken)
|
||||||
|
{{ DropdownButton::success_lg(trans('texts.pay_now'), [
|
||||||
|
['url' => URL::to("payment/{$invitation->invitation_key}?use_token=true"), 'label' => trans('texts.use_card_on_file')],
|
||||||
|
['url' => URL::to('payment/' . $invitation->invitation_key), 'label' => trans('texts.edit_payment_details')]
|
||||||
|
])->addClass('btn-lg') }}
|
||||||
|
@else
|
||||||
|
{{ Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) }}
|
||||||
|
@endif
|
||||||
@else
|
@else
|
||||||
{{ Button::success('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
|
{{ Button::success('Download PDF', array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) }}
|
||||||
@endif
|
@endif
|
||||||
|
@ -196,7 +196,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(isset($acceptedCreditCardTypes))
|
@if ($account->showTokenCheckbox())
|
||||||
|
<div class="form-group">
|
||||||
|
<input id="token_billing" type="checkbox" name="token_billing" {{ $account->selectTokenCheckbox() ? 'CHECKED' : '' }} value="1" style="margin-left:0px; vertical-align:text-top">
|
||||||
|
<label for="token_billing" class="checkbox" style="display: inline">{{ trans('texts.token_billing') }}</label>
|
||||||
|
<span class="help-block">{{ trans('texts.token_billing_secure', ['stripe_link' => link_to('https://stripe.com/', 'Stripe.com', ['target' => '_blank'])]) }}</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
@if (isset($acceptedCreditCardTypes))
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="form-group col-md-12">
|
<div class="form-group col-md-12">
|
||||||
@foreach ($acceptedCreditCardTypes as $card)
|
@foreach ($acceptedCreditCardTypes as $card)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user