mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Testing adding Stripe credit card
- Added: iframeLoaded method for Cypress - Fixed: saving payment method id for CreditCard.php - Added: chromeWebSecurity: false flag for insecure iframe connections - Formatted: payment_methods/index - Formatted: payment-methods-table.blade.php - Added: Test for adding credit card to Stripe - Fixed: Removing client gateway tokens
This commit is contained in:
parent
107e3faa6e
commit
4918269bf2
@ -48,7 +48,7 @@ class PaymentMethodController extends Controller
|
||||
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod(GatewayType::BANK_TRANSFER)
|
||||
->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
->authorizeView($data);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ class PaymentMethodController extends Controller
|
||||
|
||||
return $gateway
|
||||
->driver(auth()->user()->client)
|
||||
->setPaymentMethod(GatewayType::BANK_TRANSFER)
|
||||
->setPaymentMethod(GatewayType::CREDIT_CARD)
|
||||
->authorizeResponse($request);
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ class PaymentMethodController extends Controller
|
||||
public function destroy(ClientGatewayToken $payment_method)
|
||||
{
|
||||
try {
|
||||
event(new MethodDeleted($payment_method));
|
||||
event(new MethodDeleted($payment_method, auth('contact')->user()->company));
|
||||
$payment_method->delete();
|
||||
} catch (\Exception $e) {
|
||||
Log::error(json_encode($e));
|
||||
|
@ -45,7 +45,7 @@ class CreditCard
|
||||
$server_response = json_decode($request->input('gateway_response'));
|
||||
|
||||
$gateway_id = $request->input('gateway_id');
|
||||
$gateway_type_id = $request->input('gateway_type_id');
|
||||
$gateway_type_id = $request->input('payment_method_id');
|
||||
$is_default = $request->input('is_default');
|
||||
|
||||
$payment_method = $server_response->payment_method;
|
||||
@ -192,7 +192,7 @@ class CreditCard
|
||||
];
|
||||
|
||||
SystemLogger::dispatch($logger_message, SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_SUCCESS, SystemLog::TYPE_STRIPE, $this->stripe->client);
|
||||
|
||||
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"video": false,
|
||||
"baseUrl": "http://invoiceninja.wip/"
|
||||
"baseUrl": "http://invoiceninja.wip/",
|
||||
"chromeWebSecurity": false
|
||||
}
|
||||
|
@ -19,6 +19,35 @@ context('Payment methods', () => {
|
||||
.should('contain.text', 'Payment Method');
|
||||
});
|
||||
|
||||
it('should add stripe credit card', () => {
|
||||
cy.visit('/client/payment_methods');
|
||||
|
||||
cy.get('body')
|
||||
.find('#add-payment-method')
|
||||
.first()
|
||||
.should('contain.text', 'Add Payment Method')
|
||||
.click()
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq('/client/payment_methods/create');
|
||||
});
|
||||
|
||||
cy.wait(3000);
|
||||
|
||||
cy.get('#cardholder-name').type('Invoice Ninja');
|
||||
|
||||
cy.getWithinIframe('[name="cardnumber"]').type('4242424242424242');
|
||||
cy.getWithinIframe('[name="exp-date"]').type('2442');
|
||||
cy.getWithinIframe('[name="cvc"]').type('242');
|
||||
cy.getWithinIframe('[name="postal"]').type('12345');
|
||||
|
||||
cy.get('#card-button').click();
|
||||
|
||||
cy.location().should(location => {
|
||||
expect(location.pathname).to.eq('/client/payment_methods');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have per page options dropdown', () => {
|
||||
cy.visit('/client/payment_methods');
|
||||
|
||||
|
30
cypress/support/commands.js
vendored
30
cypress/support/commands.js
vendored
@ -44,3 +44,33 @@ Cypress.Commands.add('clientLogin', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add(
|
||||
'iframeLoaded',
|
||||
{prevSubject: 'element'},
|
||||
($iframe) => {
|
||||
const contentWindow = $iframe.prop('contentWindow');
|
||||
return new Promise(resolve => {
|
||||
if (
|
||||
contentWindow
|
||||
) {
|
||||
resolve(contentWindow)
|
||||
} else {
|
||||
$iframe.on('load', () => {
|
||||
resolve(contentWindow)
|
||||
})
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
Cypress.Commands.add(
|
||||
'getInDocument',
|
||||
{prevSubject: 'Permission denied to access property "document" on cross-origin object'},
|
||||
(document, selector) => Cypress.$(selector, document)
|
||||
);
|
||||
|
||||
Cypress.Commands.add(
|
||||
'getWithinIframe',
|
||||
(targetElement) => cy.get('iframe').iframeLoaded().its('document').getInDocument(targetElement)
|
||||
);
|
||||
|
@ -10,81 +10,85 @@
|
||||
</select>
|
||||
</div>
|
||||
@if($client->getCreditCardGateway())
|
||||
<a href="{{ route('client.payment_methods.create') }}" class="button button-primary">{{ ctrans('texts.add_payment_method') }}</a>
|
||||
<a href="{{ route('client.payment_methods.create') }}" id="add-payment-method"
|
||||
class="button button-primary">{{ ctrans('texts.add_payment_method') }}</a>
|
||||
@endif
|
||||
</div>
|
||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||
<div class="align-middle inline-block min-w-full overflow-hidden rounded">
|
||||
<table class="min-w-full shadow rounded border border-gray-200 mt-4 payment-methods-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<tr>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<span role="button" wire:click="sortBy('created_at')" class="cursor-pointer">
|
||||
{{ ctrans('texts.created_at') }}
|
||||
</span>
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
<span role="button" wire:click="sortBy('type_id')" class="cursor-pointer">
|
||||
{{ ctrans('texts.payment_type_id') }}
|
||||
</span>
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.type') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.expires') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.card_number') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.default') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||
</tr>
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.type') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.expires') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.card_number') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
|
||||
{{ ctrans('texts.default') }}
|
||||
</th>
|
||||
<th class="px-6 py-3 border-b border-gray-200 bg-gray-50"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse($payment_methods as $payment_method)
|
||||
<tr class="bg-white group hover:bg-gray-100">
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ $payment_method->formatDateTimestamp($payment_method->created_at, $client->date_format()) }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
||||
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@isset($payment_method->meta->last4)
|
||||
**** {{ $payment_method->meta->last4 }}
|
||||
@endisset
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@if($payment_method->is_default)
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check">
|
||||
<path d="M20 6L9 17l-5-5" />
|
||||
</svg>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}" class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||
@lang('texts.view')
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr class="bg-white group hover:bg-gray-100">
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500" colspan="100%">
|
||||
{{ ctrans('texts.no_results') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
@forelse($payment_methods as $payment_method)
|
||||
<tr class="bg-white group hover:bg-gray-100">
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ $payment_method->formatDateTimestamp($payment_method->created_at, $client->date_format()) }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ ctrans("texts.{$payment_method->gateway_type->alias}") }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
{{ ucfirst(optional($payment_method->meta)->brand) }}
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@if(isset($payment_method->meta->exp_month) && isset($payment_method->meta->exp_year))
|
||||
{{ $payment_method->meta->exp_month}} / {{ $payment_method->meta->exp_year }}
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@isset($payment_method->meta->last4)
|
||||
**** {{ $payment_method->meta->last4 }}
|
||||
@endisset
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500">
|
||||
@if($payment_method->is_default)
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round"
|
||||
stroke-linejoin="round" class="feather feather-check">
|
||||
<path d="M20 6L9 17l-5-5"/>
|
||||
</svg>
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-no-wrap flex items-center justify-end text-sm leading-5 font-medium">
|
||||
<a href="{{ route('client.payment_methods.show', $payment_method->hashed_id) }}"
|
||||
class="text-blue-600 hover:text-indigo-900 focus:outline-none focus:underline">
|
||||
@lang('texts.view')
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr class="bg-white group hover:bg-gray-100">
|
||||
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500" colspan="100%">
|
||||
{{ ctrans('texts.no_results') }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -95,6 +99,7 @@
|
||||
{{ ctrans('texts.showing_x_of', ['first' => $payment_methods->firstItem(), 'last' => $payment_methods->lastItem(), 'total' => $payment_methods->total()]) }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{ $payment_methods->links() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,16 +1,8 @@
|
||||
@extends('portal.ninja2020.layout.app')
|
||||
@section('meta_title', ctrans('texts.payment_methods'))
|
||||
|
||||
@section('header')
|
||||
<div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center">
|
||||
<div class="inline-flex rounded-md shadow-sm">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('body')
|
||||
<div class="flex flex-col">
|
||||
@livewire('payment-methods-table', ['client' => $client])
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
Loading…
x
Reference in New Issue
Block a user