mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-04 02:14:36 -04:00
Merge pull request #4083 from beganovich/v2-1609-detach-from-gateway
Detach payment methods from gateways
This commit is contained in:
commit
e3b9e0e12e
@ -135,6 +135,13 @@ class PaymentMethodController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function destroy(ClientGatewayToken $payment_method)
|
public function destroy(ClientGatewayToken $payment_method)
|
||||||
{
|
{
|
||||||
|
$gateway = $this->getClientGateway();
|
||||||
|
|
||||||
|
$gateway
|
||||||
|
->driver(auth()->user()->client)
|
||||||
|
->setPaymentMethod(request()->query('method'))
|
||||||
|
->detach($payment_method);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
event(new MethodDeleted($payment_method, auth('contact')->user()->company, Ninja::eventVars()));
|
event(new MethodDeleted($payment_method, auth('contact')->user()->company, Ninja::eventVars()));
|
||||||
$payment_method->delete();
|
$payment_method->delete();
|
||||||
|
@ -143,4 +143,15 @@ class AuthorizePaymentDriver extends BaseDriver
|
|||||||
|
|
||||||
return $this->payment_method->tokenBilling($cgt, $payment_hash);
|
return $this->payment_method->tokenBilling($cgt, $payment_hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach payment method from Authorize.net.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClientGatewayToken $token
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detach(ClientGatewayToken $token)
|
||||||
|
{
|
||||||
|
// Authorize.net doesn't support this feature.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,4 +75,15 @@ class CustomPaymentDriver extends BaseDriver
|
|||||||
public function processPaymentResponse($request)
|
public function processPaymentResponse($request)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach payment method from custom payment driver.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClientGatewayToken $token
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detach(ClientGatewayToken $token)
|
||||||
|
{
|
||||||
|
// Driver doesn't support this feature.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,4 +322,15 @@ class PayPalExpressPaymentDriver extends BasePaymentDriver
|
|||||||
'code' => $response->getData()['L_ERRORCODE0'],
|
'code' => $response->getData()['L_ERRORCODE0'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach payment method from PayPal.
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClientGatewayToken $token
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function detach(ClientGatewayToken $token)
|
||||||
|
{
|
||||||
|
// PayPal doesn't support this feature.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
$customer = \Stripe\Customer::create($data);
|
$customer = \Stripe\Customer::create($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $customer) {
|
if (!$customer) {
|
||||||
throw new \Exception('Unable to create gateway customer');
|
throw new \Exception('Unable to create gateway customer');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +379,7 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
* @param float $amount The amount of the payment
|
* @param float $amount The amount of the payment
|
||||||
* @return Payment The payment object
|
* @return Payment The payment object
|
||||||
*/
|
*/
|
||||||
public function createPaymentRecord($data, $amount) :?Payment
|
public function createPaymentRecord($data, $amount): ?Payment
|
||||||
{
|
{
|
||||||
$payment = PaymentFactory::create($this->client->company_id, $this->client->user_id);
|
$payment = PaymentFactory::create($this->client->company_id, $this->client->user_id);
|
||||||
$payment->client_id = $this->client->id;
|
$payment->client_id = $this->client->id;
|
||||||
@ -395,4 +395,26 @@ class StripePaymentDriver extends BasePaymentDriver
|
|||||||
|
|
||||||
return $payment->service()->applyNumber()->save();
|
return $payment->service()->applyNumber()->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detach payment method from the Stripe.
|
||||||
|
* https://stripe.com/docs/api/payment_methods/detach
|
||||||
|
*
|
||||||
|
* @param \App\Models\ClientGatewayToken $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function detach(ClientGatewayToken $token)
|
||||||
|
{
|
||||||
|
$stripe = new \Stripe\StripeClient(
|
||||||
|
$this->company_gateway->getConfigField('apiKey')
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$response = $stripe->paymentMethods->detach($token->token);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
SystemLogger::dispatch([
|
||||||
|
'server_response' => $response, 'data' => request()->all(),
|
||||||
|
], SystemLog::CATEGORY_GATEWAY_RESPONSE, SystemLog::EVENT_GATEWAY_FAILURE, SystemLog::TYPE_STRIPE, $this->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<div x-show="open" class="fixed bottom-0 inset-x-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
<div x-show="open" class="fixed inset-x-0 bottom-0 px-4 pb-4 sm:inset-0 sm:flex sm:items-center sm:justify-center">
|
||||||
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0"
|
<div x-show="open" x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0"
|
||||||
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200"
|
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200"
|
||||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
||||||
@ -11,17 +11,17 @@
|
|||||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100" x-transition:leave="ease-in duration-200"
|
||||||
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
||||||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
class="bg-white rounded-lg px-4 pt-5 pb-4 overflow-hidden shadow-xl transform transition-all sm:max-w-lg sm:w-full sm:p-6">
|
class="px-4 pt-5 pb-4 overflow-hidden transition-all transform bg-white rounded-lg shadow-xl sm:max-w-lg sm:w-full sm:p-6">
|
||||||
<div class="sm:flex sm:items-start">
|
<div class="sm:flex sm:items-start">
|
||||||
<div
|
<div
|
||||||
class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
|
class="flex items-center justify-center flex-shrink-0 w-12 h-12 mx-auto bg-red-100 rounded-full sm:mx-0 sm:h-10 sm:w-10">
|
||||||
<svg class="h-6 w-6 text-red-600" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
<svg class="w-6 h-6 text-red-600" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
|
||||||
<h3 class="text-lg leading-6 font-medium text-gray-900" translate>
|
<h3 class="text-lg font-medium leading-6 text-gray-900" translate>
|
||||||
{{ ctrans('texts.confirmation') }}
|
{{ ctrans('texts.confirmation') }}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
|
||||||
<div class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
|
<div class="flex w-full rounded-md shadow-sm sm:ml-3 sm:w-auto">
|
||||||
<form action="{{ route('client.payment_methods.destroy', $payment_method->hashed_id) }}" method="post">
|
<form action="{{ route('client.payment_methods.destroy', [$payment_method->hashed_id, 'method' => $payment_method->gateway_type->id]) }}" method="post">
|
||||||
@csrf
|
@csrf
|
||||||
@method('DELETE')
|
@method('DELETE')
|
||||||
<button type="submit" class="button button-danger button-block">
|
<button type="submit" class="button button-danger button-block">
|
||||||
@ -41,7 +41,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 flex w-full rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
<div class="flex w-full mt-3 rounded-md shadow-sm sm:mt-0 sm:w-auto">
|
||||||
|
|
||||||
<button @click="open = false" type="button" class="button button-secondary button-block">
|
<button @click="open = false" type="button" class="button button-secondary button-block">
|
||||||
{{ ctrans('texts.cancel') }}
|
{{ ctrans('texts.cancel') }}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user