1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00
invoiceninja/app/PaymentDrivers/Stripe/BrowserPay.php

253 lines
7.9 KiB
PHP
Raw Normal View History

2021-10-31 14:45:01 +01:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2021. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://opensource.org/licenses/AAL
*/
namespace App\PaymentDrivers\Stripe;
2021-11-01 14:39:18 +01:00
use App\Exceptions\PaymentFailed;
2021-10-31 14:45:01 +01:00
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
2021-11-01 14:39:18 +01:00
use App\Jobs\Util\SystemLogger;
use App\Models\GatewayType;
use App\Models\Payment;
use App\Models\PaymentType;
use App\Models\SystemLog;
use App\PaymentDrivers\Common\MethodInterface;
2021-10-31 15:12:02 +01:00
use App\PaymentDrivers\StripePaymentDriver;
use App\Utils\Ninja;
2021-10-31 14:52:15 +01:00
use Illuminate\Http\RedirectResponse;
2021-11-01 14:39:18 +01:00
use Illuminate\Http\Request;
2021-10-31 16:49:58 +01:00
use Illuminate\View\View;
2021-10-31 15:12:02 +01:00
use Stripe\ApplePayDomain;
use Stripe\Exception\ApiErrorException;
2021-11-01 14:39:18 +01:00
use Stripe\PaymentIntent;
2021-10-31 14:45:01 +01:00
class BrowserPay implements MethodInterface
{
2021-10-31 15:12:02 +01:00
protected StripePaymentDriver $stripe;
public function __construct(StripePaymentDriver $stripe)
{
$this->stripe = $stripe;
$this->stripe->init();
$this->ensureApplePayDomainIsValidated();
}
2021-10-31 14:52:15 +01:00
/**
* Authorization page for browser pay.
2021-11-01 14:39:18 +01:00
*
* @param array $data
* @return RedirectResponse
2021-10-31 14:52:15 +01:00
*/
public function authorizeView(array $data): RedirectResponse
{
return redirect()->route('client.payment_methods.index');
}
2021-10-31 14:45:01 +01:00
2021-10-31 14:52:15 +01:00
/**
* Handle the authorization for browser pay.
2021-11-01 14:39:18 +01:00
*
* @param Request $request
* @return RedirectResponse
2021-10-31 14:52:15 +01:00
*/
public function authorizeResponse(Request $request): RedirectResponse
{
return redirect()->route('client.payment_methods.index');
}
2021-10-31 14:45:01 +01:00
2021-10-31 16:49:58 +01:00
public function paymentView(array $data): View
{
$payment_intent_data = [
'amount' => $this->stripe->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
'currency' => $this->stripe->client->getCurrencyCode(),
'customer' => $this->stripe->findOrCreateCustomer(),
'description' => $this->stripe->decodeUnicodeString(ctrans('texts.invoices') . ': ' . collect($data['invoices'])->pluck('invoice_number')),
];
$data['gateway'] = $this->stripe;
$data['pi_client_secret'] = $this->stripe->createPaymentIntent($payment_intent_data)->client_secret;
$data['payment_request_data'] = [
'country' => $this->stripe->client->country->iso_3166_2,
'currency' => strtolower(
$this->stripe->client->getCurrencyCode()
),
'total' => [
'label' => $payment_intent_data['description'],
'amount' => $payment_intent_data['amount'],
],
'requestPayerName' => true,
'requestPayerEmail' => true
];
2021-11-01 14:39:18 +01:00
return render('gateways.stripe.browser_pay.pay', $data);
}
/**
* Handle payment response for browser pay.
*
* @param PaymentResponseRequest $request
* @return RedirectResponse|App\PaymentDrivers\Stripe\never
*/
public function paymentResponse(PaymentResponseRequest $request)
{
$gateway_response = json_decode($request->gateway_response);
$this->stripe->payment_hash
->withData('gateway_response', $gateway_response)
->withData('payment_intent', PaymentIntent::retrieve($gateway_response->id, $this->stripe->stripe_connect_auth));
if ($gateway_response->status === 'succeeded') {
return $this->processSuccessfulPayment();
}
return $this->processUnsuccessfulPayment();
2021-10-31 16:49:58 +01:00
}
2021-10-31 14:45:01 +01:00
2021-11-01 14:39:18 +01:00
/**
* Handle successful payment for browser pay.
*
* @return RedirectResponse
*/
protected function processSuccessfulPayment()
{
$gateway_response = $this->stripe->payment_hash->data->gateway_response;
$payment_intent = $this->stripe->payment_hash->data->payment_intent;
$this->stripe->logSuccessfulGatewayResponse(['response' => $gateway_response, 'data' => $this->stripe->payment_hash], SystemLog::TYPE_STRIPE);
$payment_method = $this->stripe->getStripePaymentMethod($gateway_response->payment_method);
$data = [
'payment_method' => $gateway_response->payment_method,
'payment_type' => PaymentType::parseCardType(strtolower($payment_method->card->brand)),
'amount' => $this->stripe->convertFromStripeAmount($gateway_response->amount, $this->stripe->client->currency()->precision, $this->stripe->client->currency()),
'transaction_reference' => optional($payment_intent->charges->data[0])->id,
'gateway_type_id' => GatewayType::APPLE_PAY,
];
$this->stripe->payment_hash->data = array_merge((array) $this->stripe->payment_hash->data, ['amount' => $data['amount']]);
$this->stripe->payment_hash->save();
$payment = $this->stripe->createPayment($data, Payment::STATUS_COMPLETED);
SystemLogger::dispatch(
['response' => $gateway_response, 'data' => $data],
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_SUCCESS,
SystemLog::TYPE_STRIPE,
$this->stripe->client,
$this->stripe->client->company,
);
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
}
/**
* Handle unsuccessful payment for browser pay.
*
* @return never
*/
protected function processUnsuccessfulPayment()
{
$server_response = $this->stripe->payment_hash->data->gateway_response;
$this->stripe->sendFailureMail($server_response->cancellation_reason);
$message = [
'server_response' => $server_response,
'data' => $this->stripe->payment_hash->data,
];
SystemLogger::dispatch(
$message,
SystemLog::CATEGORY_GATEWAY_RESPONSE,
SystemLog::EVENT_GATEWAY_FAILURE,
SystemLog::TYPE_STRIPE,
$this->stripe->client,
$this->stripe->client->company,
);
throw new PaymentFailed('Failed to process the payment.', 500);
}
2021-10-31 15:12:02 +01:00
/**
* Ensure Apple Pay domain is verified.
2021-11-01 14:39:18 +01:00
*
* @return void
* @throws ApiErrorException
2021-10-31 15:12:02 +01:00
*/
protected function ensureApplePayDomainIsValidated()
{
$config = $this->stripe->company_gateway->getConfig();
if (property_exists($config, 'apple_pay_domain_id')) {
return;
}
2022-01-10 02:47:16 +01:00
// $domain = config('ninja.app_url');
2021-10-31 15:12:02 +01:00
2022-01-10 02:47:16 +01:00
// if (Ninja::isHosted()) {
// $domain = isset($this->stripe->company_gateway->company->portal_domain)
// ? $this->stripe->company_gateway->company->portal_domain
// : $this->stripe->company_gateway->company->domain();
// }
$domain = $this->getAppleDomain();
if(!$domain)
throw new PaymentFailed('Unable to register Domain with Apple Pay', 500);
2021-10-31 15:12:02 +01:00
$response = ApplePayDomain::create([
'domain_name' => $domain,
]);
$config->apple_pay_domain_id = $response->id;
$this->stripe->company_gateway->setConfig($config);
$this->stripe->company_gateway->save();
}
2022-01-10 02:47:16 +01:00
private function getAppleDomain()
{
$domain = '';
if(Ninja::isHosted())
{
if($this->company_gateway->company->portal_mode == 'domain'){
$domain = $this->company_gateway->company->portal_domain;
}
else{
$domain = $this->company_gateway->company->subdomain . '.' . config('ninja.app_domain');
}
}
else {
$domain = config('ninja.app_url');
}
$parsed_url = parse_url($domain);
if(array_key_exists('host', $parsed_url))
return $parsed_url['host'];
return false;
}
2021-11-01 14:39:18 +01:00
}