diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index f5ecc89f8e8e..b23f0cb7b7ab 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -55,6 +55,7 @@ class PaymentController extends BaseController 'client', 'transaction_reference', 'method', + 'source', 'payment_amount', 'payment_date', 'status', @@ -439,10 +440,12 @@ class PaymentController extends BaseController if ($useToken) { $details['customerReference'] = $client->getGatewayToken(); + 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); + $token = $this->paymentService->createToken($gateway, $details, $accountGateway, $client, $invitation->contact_id, $customerReference); if ($token) { - $details['customerReference'] = $token; + $details['token'] = $token; + $details['customerReference'] = $customerReference; } else { $this->error('Token-No-Ref', $this->paymentService->lastError, $accountGateway); return Redirect::to('payment/'.$invitationKey)->withInput(Request::except('cvv')); @@ -479,7 +482,49 @@ class PaymentController extends BaseController } if ($response->isSuccessful()) { - $payment = $this->paymentService->createPayment($invitation, $accountGateway, $ref); + $last4 = null; + $expiration = null; + $card_type_id = null; + + if (!empty($details['card'])) { + $card = $details['card']; + $last4 = substr($card->number, -4); + $year = $card->expiryYear; + if (strlen($year) == 2) { + $year = '20' . $year; + } + + $expiration = $year . '-' . $card->expiryMonth . '-00'; + $card_type_id = $this->detectCardType($card->number); + } + + if ($accountGateway->gateway_id == GATEWAY_STRIPE) { + $card = $response->getSource(); + if (!$card) { + $card = $response->getCard(); + } + + if ($card) { + $last4 = $card['last4']; + $expiration = $card['exp_year'] . '-' . $card['exp_month'] . '-00'; + $stripe_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 + ); + + if (!empty($stripe_card_types[$card['brand']])) { + $card_type_id = $stripe_card_types[$card['brand']]; + } else { + $card_type_id = CARD_UNKNOWN; + } + } + } + + $payment = $this->paymentService->createPayment($invitation, $accountGateway, $ref, null, $last4, $expiration, $card_type_id); Session::flash('message', trans('texts.applied_payment')); if ($account->account_key == NINJA_ACCOUNT_KEY) { @@ -512,6 +557,24 @@ class PaymentController extends BaseController } } } + + private function detectCardType($number) + { + if (preg_match('/^3[47][0-9]{13}$/',$number)) { + return CARD_AMERICAN_EXPRESS; + } elseif (preg_match('/^3(?:0[0-5]|[68][0-9])[0-9]{11}$/',$number)) { + return CARD_DINERS_CLUB; + } elseif (preg_match('/^6(?:011|5[0-9][0-9])[0-9]{12}$/',$number)) { + return CARD_DISCOVER; + } elseif (preg_match('/^(?:2131|1800|35\d{3})\d{11}$/',$number)) { + return CARD_JCB; + } elseif (preg_match('/^5[1-5][0-9]{14}$/',$number)) { + return CARD_MASTERCARD; + } elseif (preg_match('/^4[0-9]{12}(?:[0-9]{3})?$/',$number)) { + return CARD_VISA; + } + return CARD_UNKNOWN; + } public function offsite_payment() { diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php index d756bd7eaaa0..085098827e1b 100644 --- a/app/Http/Controllers/PublicClientController.php +++ b/app/Http/Controllers/PublicClientController.php @@ -324,7 +324,7 @@ class PublicClientController extends BaseController 'clientFontUrl' => $account->getFontsUrl(), 'entityType' => ENTITY_PAYMENT, 'title' => trans('texts.payments'), - 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'payment_amount', 'payment_date', 'status']) + 'columns' => Utils::trans(['invoice', 'transaction_reference', 'method', 'source', 'payment_amount', 'payment_date', 'status']) ]; return response()->view('public_list', $data); @@ -341,9 +341,16 @@ class PublicClientController extends BaseController ->addColumn('invoice_number', function ($model) { return $model->invitation_key ? link_to('/view/'.$model->invitation_key, $model->invoice_number)->toHtml() : $model->invoice_number; }) ->addColumn('transaction_reference', function ($model) { return $model->transaction_reference ? $model->transaction_reference : 'Manual entry'; }) ->addColumn('payment_type', function ($model) { return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? 'Online payment' : ''); }) + ->addColumn('payment_source', function ($model) { + if (!$model->card_type_code) return ''; + $card_type = trans("texts.card_" . $model->card_type_code); + $expiration = trans('texts.card_expiration', array('expires'=>Utils::fromSqlDate($model->expiration, false)->format('m/d'))); + return ''.htmlentities($card_type).'  •••'.$model->last4.' '.$expiration; + }) ->addColumn('amount', function ($model) { return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id); }) ->addColumn('payment_date', function ($model) { return Utils::dateToString($model->payment_date); }) ->addColumn('status', function ($model) { return $this->getPaymentStatusLabel($model); }) + ->orderColumns( 'invoice_number', 'transaction_reference', 'payment_type', 'amount', 'payment_date') ->make(); } diff --git a/app/Http/routes.php b/app/Http/routes.php index 25041048f102..9903b3caee0f 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -481,6 +481,20 @@ if (!defined('CONTACT_EMAIL')) { define('PAYMENT_STATUS_COMPLETED', 3); define('PAYMENT_STATUS_PARTIALLY_REFUNDED', 4); define('PAYMENT_STATUS_REFUNDED', 5); + + define('CARD_UNKNOWN', 0); + define('CARD_AMERICAN_EXPRESS', 1); + define('CARD_CARTE_BLANCHE', 2); + define('CARD_UNIONPAY', 3); + define('CARD_DINERS_CLUB', 4); + define('CARD_DISCOVER', 5); + define('CARD_JCB', 6); + define('CARD_LASER', 7); + define('CARD_MAISTRO', 8); + define('CARD_MASTERCARD', 9); + define('CARD_SOLO', 10); + define('CARD_SWITCH', 11); + define('CARD_VISA', 12); define('PAYMENT_TYPE_CREDIT', 1); define('CUSTOM_DESIGN', 11); diff --git a/app/Models/CardType.php b/app/Models/CardType.php new file mode 100644 index 000000000000..6eee490c1260 --- /dev/null +++ b/app/Models/CardType.php @@ -0,0 +1,8 @@ +belongsTo('App\Models\PaymentStatus'); + } + + public function card_type() + { + return $this->belongsTo('App\Models\CardTypes'); } public function getRoute() diff --git a/app/Ninja/Repositories/PaymentRepository.php b/app/Ninja/Repositories/PaymentRepository.php index 668b5b85d9ee..be2a9104b576 100644 --- a/app/Ninja/Repositories/PaymentRepository.php +++ b/app/Ninja/Repositories/PaymentRepository.php @@ -23,6 +23,7 @@ class PaymentRepository extends BaseRepository ->join('invoices', 'invoices.id', '=', 'payments.invoice_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->join('payment_statuses', 'payment_statuses.id', '=', 'payments.payment_status_id') + ->join('card_types', 'card_types.id', '=', 'payments.card_type_id') ->leftJoin('payment_types', 'payment_types.id', '=', 'payments.payment_type_id') ->leftJoin('account_gateways', 'account_gateways.id', '=', 'payments.account_gateway_id') ->leftJoin('gateways', 'gateways.id', '=', 'account_gateways.gateway_id') @@ -54,10 +55,13 @@ class PaymentRepository extends BaseRepository 'payments.is_deleted', 'payments.user_id', 'payments.refunded', + 'payments.expiration', + 'payments.last4', 'invoices.is_deleted as invoice_is_deleted', 'gateways.name as gateway_name', 'gateways.id as gateway_id', - 'payment_statuses.name as payment_status_name' + 'payment_statuses.name as payment_status_name', + 'card_types.code as card_type_code' ); if (!\Session::get('show_trash:payment')) { @@ -85,6 +89,7 @@ class PaymentRepository extends BaseRepository ->join('invoices', 'invoices.id', '=', 'payments.invoice_id') ->join('contacts', 'contacts.client_id', '=', 'clients.id') ->join('payment_statuses', 'payment_statuses.id', '=', 'payments.payment_status_id') + ->join('card_types', 'card_types.id', '=', 'payments.card_type_id') ->leftJoin('invitations', function ($join) { $join->on('invitations.invoice_id', '=', 'invoices.id') ->on('invitations.contact_id', '=', 'contacts.id'); @@ -113,8 +118,11 @@ class PaymentRepository extends BaseRepository 'payment_types.name as payment_type', 'payments.account_gateway_id', 'payments.refunded', + 'payments.expiration', + 'payments.last4', 'payments.payment_status_id', - 'payment_statuses.name as payment_status_name' + 'payment_statuses.name as payment_status_name', + 'card_types.code as card_type_code' ); if ($filter) { diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index b68b06482a04..4cd0c615c024 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -29,12 +29,12 @@ class BaseService return count($entities); } - public function createDatatable($entityType, $query, $showCheckbox = true, $hideClient = false) + public function createDatatable($entityType, $query, $showCheckbox = true, $hideClient = false, $orderColumns = []) { $columns = $this->getDatatableColumns($entityType, !$showCheckbox); $actions = $this->getDatatableActions($entityType); - return $this->datatableService->createDatatable($entityType, $query, $columns, $actions, $showCheckbox); + return $this->datatableService->createDatatable($entityType, $query, $columns, $actions, $showCheckbox, $orderColumns); } protected function getDatatableColumns($entityType, $hideClient) diff --git a/app/Services/DatatableService.php b/app/Services/DatatableService.php index 2f9af2856cf3..3d9001a095b7 100644 --- a/app/Services/DatatableService.php +++ b/app/Services/DatatableService.php @@ -7,11 +7,11 @@ use Auth; class DatatableService { - public function createDatatable($entityType, $query, $columns, $actions = null, $showCheckbox = true) + public function createDatatable($entityType, $query, $columns, $actions = null, $showCheckbox = true, $orderColumns = []) { $table = Datatable::query($query); - $orderColumns = []; - + $calculateOrderColumns = empty($orderColumns); + if ($actions && $showCheckbox) { $table->addColumn('checkbox', function ($model) { $can_edit = Auth::user()->hasPermission('edit_all') || (isset($model->user_id) && Auth::user()->id == $model->user_id); @@ -31,7 +31,9 @@ class DatatableService if ($visible) { $table->addColumn($field, $value); - $orderColumns[] = $field; + if ($calculateOrderColumns) { + $orderColumns[] = $field; + } } } diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index 8e24370bd930..7756071348ca 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -75,7 +75,7 @@ class PaymentService extends BaseService $data = $this->createDataForClient($invitation); } - $card = new CreditCard($data); + $card = !empty($data['number']) ? new CreditCard($data) : null; $data = [ 'amount' => $invoice->getRequestedAmount(), 'card' => $card, @@ -155,12 +155,21 @@ class PaymentService extends BaseService ]; } - public function createToken($gateway, $details, $accountGateway, $client, $contactId) + public function createToken($gateway, $details, $accountGateway, $client, $contactId, &$customerReference = null) { $tokenResponse = $gateway->createCard($details)->send(); - $cardReference = $tokenResponse->getCustomerReference(); + $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 ($cardReference) { + if ($customerReference) { $token = AccountGatewayToken::where('client_id', '=', $client->id) ->where('account_gateway_id', '=', $accountGateway->id)->first(); @@ -172,7 +181,7 @@ class PaymentService extends BaseService $token->client_id = $client->id; } - $token->token = $cardReference; + $token->token = $customerReference; $token->save(); } else { $this->lastError = $tokenResponse->getMessage(); @@ -205,7 +214,7 @@ class PaymentService extends BaseService return $token; } - public function createPayment($invitation, $accountGateway, $ref, $payerId = null) + public function createPayment($invitation, $accountGateway, $ref, $payerId = null, $last4 = null, $expiration = null, $card_type_id = null, $routing_number = null) { $invoice = $invitation->invoice; @@ -218,6 +227,10 @@ class PaymentService extends BaseService $payment->contact_id = $invitation->contact_id; $payment->transaction_reference = $ref; $payment->payment_date = date_create()->format('Y-m-d'); + $payment->last4 = $last4; + $payment->expiration = $expiration; + $payment->card_type_id = $card_type_id; + $payment->routing_number = $routing_number; if ($payerId) { $payment->payer_id = $payerId; @@ -329,7 +342,8 @@ class PaymentService extends BaseService $query->where('payments.user_id', '=', Auth::user()->id); } - return $this->createDatatable(ENTITY_PAYMENT, $query, !$clientPublicId); + return $this->createDatatable(ENTITY_PAYMENT, $query, !$clientPublicId, false, + ['invoice_number', 'transaction_reference', 'payment_type', 'amount', 'payment_date']); } protected function getDatatableColumns($entityType, $hideClient) @@ -368,6 +382,15 @@ class PaymentService extends BaseService return $model->payment_type ? $model->payment_type : ($model->account_gateway_id ? $model->gateway_name : ''); } ], + [ + 'source', + function ($model) { + if (!$model->card_type_code) return ''; + $card_type = trans("texts.card_" . $model->card_type_code); + $expiration = trans('texts.card_expiration', array('expires'=>Utils::fromSqlDate($model->expiration, false)->format('m/d'))); + return ''.htmlentities($card_type).'  •••'.$model->last4.' '.$expiration; + } + ], [ 'amount', function ($model) { diff --git a/composer.json b/composer.json index 9bb49326b1f8..b481c5963014 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "omnipay/mollie": "dev-master#22956c1a62a9662afa5f5d119723b413770ac525", "omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248", "omnipay/gocardless": "dev-master", - "omnipay/stripe": "2.3.0", + "omnipay/stripe": "2.3.2", "laravel/framework": "5.2.*", "laravelcollective/html": "5.2.*", "laravelcollective/bus": "5.2.*", diff --git a/composer.lock b/composer.lock index 606338333d7c..d6f9646f7c2f 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "cf82d2ddb25cb1a7d6b4867bcc8692b8", - "content-hash": "481a95753b873249aebceb99e7426421", + "hash": "607b25b09aee82ac769bd942fac91ba6", + "content-hash": "122f3f59beb2286159145d219dbcbc90", "packages": [ { "name": "agmscode/omnipay-agms", @@ -127,7 +127,7 @@ }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/formers/former/zipball/78ae8c65b1f8134e2db1c9491c251c03638823ca", + "url": "https://api.github.com/repos/formers/former/zipball/37f6876a5d211427b5c445cd64f0eb637f42f685", "reference": "d97f907741323b390f43954a90a227921ecc6b96", "shasum": "" }, @@ -699,7 +699,7 @@ "laravel" ], "abandoned": "OpenSkill/Datatable", - "time": "2015-04-29 07:00:36" + "time": "2015-11-23 21:33:41" }, { "name": "classpreloader/classpreloader", @@ -5661,16 +5661,16 @@ }, { "name": "omnipay/stripe", - "version": "v2.3.0", + "version": "v2.3.2", "source": { "type": "git", "url": "https://github.com/thephpleague/omnipay-stripe.git", - "reference": "54b816a5e95e34c988d71fb805b0232cfd7c1ce5" + "reference": "fe05ddd73d9ae38ca026dbc270ca98aaf3f99da4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/54b816a5e95e34c988d71fb805b0232cfd7c1ce5", - "reference": "54b816a5e95e34c988d71fb805b0232cfd7c1ce5", + "url": "https://api.github.com/repos/thephpleague/omnipay-stripe/zipball/fe05ddd73d9ae38ca026dbc270ca98aaf3f99da4", + "reference": "fe05ddd73d9ae38ca026dbc270ca98aaf3f99da4", "shasum": "" }, "require": { @@ -5714,7 +5714,7 @@ "payment", "stripe" ], - "time": "2015-11-10 16:17:35" + "time": "2016-03-19 08:35:06" }, { "name": "omnipay/targetpay", diff --git a/database/migrations/2016_04_23_182223_payments_changes.php b/database/migrations/2016_04_23_182223_payments_changes.php index 641ec06e2c2d..fc887b3bb88f 100644 --- a/database/migrations/2016_04_23_182223_payments_changes.php +++ b/database/migrations/2016_04_23_182223_payments_changes.php @@ -13,6 +13,7 @@ class PaymentsChanges extends Migration public function up() { Schema::dropIfExists('payment_statuses'); + Schema::dropIfExists('card_types'); Schema::create('payment_statuses', function($table) { @@ -20,13 +21,27 @@ class PaymentsChanges extends Migration $table->string('name'); }); + Schema::create('card_types', function($table) + { + $table->increments('id'); + $table->string('name'); + $table->string('code'); + }); + (new \PaymentStatusSeeder())->run(); + (new \CardTypesSeeder())->run(); Schema::table('payments', function($table) { $table->decimal('refunded', 13, 2); $table->unsignedInteger('payment_status_id')->default(3); $table->foreign('payment_status_id')->references('id')->on('payment_statuses'); + + $table->unsignedInteger('routing_number')->nullable(); + $table->smallInteger('last4')->unsigned()->nullable(); + $table->date('expiration')->nullable(); + $table->unsignedInteger('card_type_id')->nullable(); + $table->foreign('card_type_id')->references('id')->on('card_types'); }); } @@ -42,8 +57,15 @@ class PaymentsChanges extends Migration $table->dropColumn('refunded'); $table->dropForeign('payments_payment_status_id_foreign'); $table->dropColumn('payment_status_id'); + + $table->dropColumn('routing_number'); + $table->dropColumn('last4'); + $table->dropColumn('expiration'); + $table->dropForeign('card_type_id_foreign'); + $table->dropColumn('card_type_id'); }); Schema::dropIfExists('payment_statuses'); + Schema::dropIfExists('card_types'); } } diff --git a/database/seeds/CardTypesSeeder.php b/database/seeds/CardTypesSeeder.php new file mode 100644 index 000000000000..e5d70b9ed585 --- /dev/null +++ b/database/seeds/CardTypesSeeder.php @@ -0,0 +1,44 @@ +createPaymentSourceTypes(); + + Eloquent::reguard(); + } + + private function createPaymentSourceTypes() + { + $statuses = [ + ['id' => '0', 'name' => 'Unknown', 'code'=>'unknown'] + ['id' => '1', 'name' => 'American Express', 'code'=>'amex'], + ['id' => '2', 'name' => 'Carte Blanche', 'code'=>'carteblanche'], + ['id' => '3', 'name' => 'China UnionPay', 'code'=>'unionpay'], + ['id' => '4', 'name' => 'Diners Club', 'code'=>'diners'], + ['id' => '5', 'name' => 'Discover', 'code'=>'discover'], + ['id' => '6', 'name' => 'JCB', 'code'=>'jcb'], + ['id' => '7', 'name' => 'Laser', 'code'=>'laser'], + ['id' => '8', 'name' => 'Maestro', 'code'=>'maestro'], + ['id' => '9', 'name' => 'MasterCard', 'code'=>'mastercard'], + ['id' => '10', 'name' => 'Solo', 'code'=>'solo'], + ['id' => '11', 'name' => 'Switch', 'code'=>'switch'], + ['id' => '12', 'name' => 'Visa', 'code'=>'visa'], + ]; + + foreach ($statuses as $status) { + $record = CardType::find($status['id']); + if ($record) { + $record->name = $status['name']; + $record->save(); + } else { + CardType::create($status); + } + } + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 753a1ce54e30..20bdbe7f0cc1 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -20,6 +20,7 @@ class DatabaseSeeder extends Seeder $this->call('BanksSeeder'); $this->call('InvoiceStatusSeeder'); $this->call('PaymentStatusSeeder'); + $this->call('CardTypesSeeder'); $this->call('CurrenciesSeeder'); $this->call('DateFormatsSeeder'); $this->call('InvoiceDesignsSeeder'); diff --git a/database/seeds/UpdateSeeder.php b/database/seeds/UpdateSeeder.php index e5335e311b42..dffb2dbe26b7 100644 --- a/database/seeds/UpdateSeeder.php +++ b/database/seeds/UpdateSeeder.php @@ -16,6 +16,7 @@ class UpdateSeeder extends Seeder $this->call('BanksSeeder'); $this->call('InvoiceStatusSeeder'); $this->call('PaymentStatusSeeder'); + $this->call('CardTypesSeeder'); $this->call('CurrenciesSeeder'); $this->call('DateFormatsSeeder'); $this->call('InvoiceDesignsSeeder'); diff --git a/public/images/credit_cards/amex.png b/public/images/credit_cards/amex.png new file mode 100644 index 000000000000..492d40aff6aa Binary files /dev/null and b/public/images/credit_cards/amex.png differ diff --git a/public/images/credit_cards/carteblanche.png b/public/images/credit_cards/carteblanche.png new file mode 100644 index 000000000000..0b8f49aa7e5b Binary files /dev/null and b/public/images/credit_cards/carteblanche.png differ diff --git a/public/images/credit_cards/diners.png b/public/images/credit_cards/diners.png new file mode 100644 index 000000000000..72e1808fb1f9 Binary files /dev/null and b/public/images/credit_cards/diners.png differ diff --git a/public/images/credit_cards/discover.png b/public/images/credit_cards/discover.png new file mode 100644 index 000000000000..7e36dd71508a Binary files /dev/null and b/public/images/credit_cards/discover.png differ diff --git a/public/images/credit_cards/jcb.png b/public/images/credit_cards/jcb.png new file mode 100644 index 000000000000..9bb0cbafdc0e Binary files /dev/null and b/public/images/credit_cards/jcb.png differ diff --git a/public/images/credit_cards/laser.png b/public/images/credit_cards/laser.png new file mode 100644 index 000000000000..2f2417942bb4 Binary files /dev/null and b/public/images/credit_cards/laser.png differ diff --git a/public/images/credit_cards/maestro.png b/public/images/credit_cards/maestro.png new file mode 100644 index 000000000000..38fdb4b7de1e Binary files /dev/null and b/public/images/credit_cards/maestro.png differ diff --git a/public/images/credit_cards/mastercard.png b/public/images/credit_cards/mastercard.png new file mode 100644 index 000000000000..af9b1d701c96 Binary files /dev/null and b/public/images/credit_cards/mastercard.png differ diff --git a/public/images/credit_cards/paypa.png b/public/images/credit_cards/paypa.png new file mode 100644 index 000000000000..4fad9d864c6b Binary files /dev/null and b/public/images/credit_cards/paypa.png differ diff --git a/public/images/credit_cards/solo.png b/public/images/credit_cards/solo.png new file mode 100644 index 000000000000..c236ecc0f71c Binary files /dev/null and b/public/images/credit_cards/solo.png differ diff --git a/public/images/credit_cards/switch.png b/public/images/credit_cards/switch.png new file mode 100644 index 000000000000..6ff522c6c14b Binary files /dev/null and b/public/images/credit_cards/switch.png differ diff --git a/public/images/credit_cards/unionpay.png b/public/images/credit_cards/unionpay.png new file mode 100644 index 000000000000..0aa7031c20f2 Binary files /dev/null and b/public/images/credit_cards/unionpay.png differ diff --git a/public/images/credit_cards/unknown.png b/public/images/credit_cards/unknown.png new file mode 100644 index 000000000000..0b8f49aa7e5b Binary files /dev/null and b/public/images/credit_cards/unknown.png differ diff --git a/public/images/credit_cards/visa.png b/public/images/credit_cards/visa.png new file mode 100644 index 000000000000..ffd17c5a280a Binary files /dev/null and b/public/images/credit_cards/visa.png differ diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index ae717b297b23..202adb8d531e 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -1190,7 +1190,21 @@ $LANG = array( 'status_refunded' => 'Refunded', 'refunded_payment' => 'Refunded Payment', 'activity_39' => ':user refunded :adjustment of a :payment_amount payment (:payment)', - + 'card_expiration' => 'Exp: :expires', + + 'card_unknown' => 'Unknown', + 'card_amex' => 'American Express', + 'card_carteblanche' => 'Carte Blanche', + 'card_unionpay' => 'UnionPay', + 'card_diners' => 'Diners Club', + 'card_discover' => 'Discover', + 'card_jcb' => 'JCB', + 'card_laser' => 'Laser', + 'card_maestro' => 'Maestro', + 'card_mastercard' => 'MasterCard', + 'card_solo' => 'Solo', + 'card_switch' => 'Switch', + 'card_visa' => 'Visa', ); return $LANG; diff --git a/resources/views/clients/show.blade.php b/resources/views/clients/show.blade.php index 0e434b3d07d4..db49da710efe 100644 --- a/resources/views/clients/show.blade.php +++ b/resources/views/clients/show.blade.php @@ -290,8 +290,10 @@ trans('texts.invoice'), trans('texts.transaction_reference'), trans('texts.method'), + trans('texts.source'), trans('texts.payment_amount'), - trans('texts.payment_date')) + trans('texts.payment_date'), + trans('texts.status')) ->setUrl(url('api/payments/' . $client->public_id)) ->setCustomValues('entityType', 'payments') ->setOptions('sPaginationType', 'bootstrap')