mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on ApplePay
This commit is contained in:
parent
6669b81c4d
commit
cde5f527e1
91
app/PaymentDrivers/Stripe/ApplePay.php
Normal file
91
app/PaymentDrivers/Stripe/ApplePay.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?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://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\PaymentDrivers\Stripe;
|
||||
|
||||
use App\Exceptions\PaymentFailed;
|
||||
use App\Http\Requests\ClientPortal\Payments\PaymentResponseRequest;
|
||||
use App\Jobs\Mail\PaymentFailureMailer;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Payment;
|
||||
use App\Models\PaymentType;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\StripePaymentDriver;
|
||||
use App\PaymentDrivers\Stripe\CreditCard;
|
||||
|
||||
class ApplePay
|
||||
{
|
||||
/** @var StripePaymentDriver */
|
||||
public $stripe_driver;
|
||||
|
||||
public function __construct(StripePaymentDriver $stripe_driver)
|
||||
{
|
||||
$this->stripe_driver = $stripe_driver;
|
||||
}
|
||||
|
||||
public function paymentView(array $data)
|
||||
{
|
||||
$data['gateway'] = $this->stripe_driver;
|
||||
$data['payment_hash'] = $this->stripe_driver->payment_hash->hash;
|
||||
$data['payment_method_id'] = GatewayType::APPLE_PAY;
|
||||
$data['country'] = $this->stripe_driver->client->country;
|
||||
$data['currency'] = $this->stripe_driver->client->currency()->code;
|
||||
$data['stripe_amount'] = $this->stripe_driver->convertToStripeAmount($data['total']['amount_with_fee'], $this->stripe_driver->client->currency()->precision, $this->stripe_driver->client->currency());
|
||||
$data['invoices'] = $this->stripe_driver->payment_hash->invoices();
|
||||
|
||||
$data['intent'] = \Stripe\PaymentIntent::create([
|
||||
'amount' => $data['stripe_amount'],
|
||||
'currency' => $this->stripe_driver->client->getCurrencyCode();,
|
||||
], $this->stripe_driver->stripe_connect_auth);
|
||||
|
||||
$this->stripe_driver->payment_hash->data = array_merge((array) $this->stripe_driver->payment_hash->data, ['stripe_amount' => $data['stripe_amount']]);
|
||||
$this->stripe_driver->payment_hash->save();
|
||||
|
||||
return render('gateways.stripe.applepay.pay', $data);
|
||||
}
|
||||
|
||||
|
||||
public function paymentResponse(PaymentResponseRequest $request)
|
||||
{
|
||||
|
||||
$this->stripe_driver->init();
|
||||
|
||||
$state = [
|
||||
'server_response' => json_decode($request->gateway_response),
|
||||
'payment_hash' => $request->payment_hash,
|
||||
];
|
||||
|
||||
$state['payment_intent'] = \Stripe\PaymentIntent::retrieve($state['server_response']->id, $this->stripe_driver->stripe_connect_auth);
|
||||
|
||||
$state['customer'] = $state['payment_intent']->customer;
|
||||
|
||||
$this->stripe_driver->payment_hash->data = array_merge((array) $this->stripe_driver->payment_hash->data, $state);
|
||||
$this->stripe_driver->payment_hash->save();
|
||||
|
||||
$server_response = $this->stripe_driver->payment_hash->data->server_response;
|
||||
|
||||
$response_handler = new CreditCard($this->stripe_driver);
|
||||
|
||||
if ($server_response->status == 'succeeded') {
|
||||
|
||||
$this->stripe_driver->logSuccessfulGatewayResponse(['response' => json_decode($request->gateway_response), 'data' => $this->stripe_driver->payment_hash], SystemLog::TYPE_STRIPE);
|
||||
|
||||
return $response_handler->processSuccessfulPayment();
|
||||
}
|
||||
|
||||
return $response_handler->processUnsuccessfulPayment($server_response);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -108,7 +108,7 @@ class CreditCard
|
||||
return $this->processUnsuccessfulPayment($server_response);
|
||||
}
|
||||
|
||||
private function processSuccessfulPayment()
|
||||
public function processSuccessfulPayment()
|
||||
{
|
||||
$stripe_method = $this->stripe->getStripePaymentMethod($this->stripe->payment_hash->data->server_response->payment_method);
|
||||
|
||||
@ -148,7 +148,7 @@ class CreditCard
|
||||
return redirect()->route('client.payments.show', ['payment' => $this->stripe->encodePrimaryKey($payment->id)]);
|
||||
}
|
||||
|
||||
private function processUnsuccessfulPayment($server_response)
|
||||
public function processUnsuccessfulPayment($server_response)
|
||||
{
|
||||
PaymentFailureMailer::dispatch($this->stripe->client, $server_response->cancellation_reason, $this->stripe->client->company, $server_response->amount);
|
||||
|
||||
|
@ -25,6 +25,7 @@ use App\Models\PaymentHash;
|
||||
use App\Models\SystemLog;
|
||||
use App\PaymentDrivers\Stripe\ACH;
|
||||
use App\PaymentDrivers\Stripe\Alipay;
|
||||
use App\PaymentDrivers\Stripe\ApplePay;
|
||||
use App\PaymentDrivers\Stripe\Charge;
|
||||
use App\PaymentDrivers\Stripe\Connect\Verify;
|
||||
use App\PaymentDrivers\Stripe\CreditCard;
|
||||
@ -72,7 +73,7 @@ class StripePaymentDriver extends BaseDriver
|
||||
GatewayType::BANK_TRANSFER => ACH::class,
|
||||
GatewayType::ALIPAY => Alipay::class,
|
||||
GatewayType::SOFORT => SOFORT::class,
|
||||
GatewayType::APPLE_PAY => 1, // TODO
|
||||
GatewayType::APPLE_PAY => ApplePay::class,
|
||||
GatewayType::SEPA => 1, // TODO
|
||||
];
|
||||
|
||||
|
@ -0,0 +1,112 @@
|
||||
@extends('portal.ninja2020.layout.payments', ['gateway_title' => 'Alipay', 'card_title' => 'Alipay'])
|
||||
|
||||
@section('gateway_head')
|
||||
|
||||
@endsection
|
||||
|
||||
@section('gateway_content')
|
||||
<form action="{{ route('client.payments.response') }}" method="post" id="server-response">
|
||||
@csrf
|
||||
<input type="hidden" name="gateway_response">
|
||||
<input type="hidden" name="payment_hash" value="{{ $payment_hash }}">
|
||||
<input type="hidden" name="company_gateway_id" value="{{ $gateway->getCompanyGatewayId() }}">
|
||||
<input type="hidden" name="payment_method_id" value="{{ $payment_method_id }}">
|
||||
</form>
|
||||
|
||||
<div class="alert alert-failure mb-4" hidden id="errors"></div>
|
||||
|
||||
@include('portal.ninja2020.gateways.includes.payment_details')
|
||||
|
||||
<div id="payment-request-button">
|
||||
<!-- A Stripe Element will be inserted here. -->
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@push('footer')
|
||||
<script src="https://js.stripe.com/v3/"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
@if($gateway->company_gateway->getConfigField('account_id'))
|
||||
var stripe = Stripe('{{ config('ninja.ninja_stripe_publishable_key') }}', {
|
||||
apiVersion: "2018-05-21",
|
||||
stripeAccount: '{{ $gateway->company_gateway->getConfigField('account_id') }}',
|
||||
});
|
||||
@else
|
||||
var stripe = Stripe('{{ $gateway->getPublishableKey() }}', {
|
||||
apiVersion: "2018-05-21",
|
||||
});
|
||||
@endif
|
||||
|
||||
var paymentRequest = stripe.paymentRequest({
|
||||
country: '{{ $country->iso_3166_2 }}',
|
||||
currency: '{{ $currency }}',
|
||||
total: {
|
||||
label: '{{ ctrans('texts.payment_amount') }}',
|
||||
amount: {{ $stripe_amount }},
|
||||
},
|
||||
requestPayerName: true,
|
||||
requestPayerEmail: true,
|
||||
});
|
||||
|
||||
var elements = stripe.elements();
|
||||
var prButton = elements.create('paymentRequestButton', {
|
||||
paymentRequest: paymentRequest,
|
||||
});
|
||||
|
||||
// Check the availability of the Payment Request API first.
|
||||
paymentRequest.canMakePayment().then(function(result) {
|
||||
if (result) {
|
||||
prButton.mount('#payment-request-button');
|
||||
} else {
|
||||
document.getElementById('payment-request-button').style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
paymentRequest.on('paymentmethod', function(ev) {
|
||||
// Confirm the PaymentIntent without handling potential next actions (yet).
|
||||
stripe.confirmCardPayment(
|
||||
'{{ $intent->client_secret }}',
|
||||
{payment_method: ev.paymentMethod.id},
|
||||
{handleActions: false}
|
||||
).then(function(confirmResult) {
|
||||
if (confirmResult.error) {
|
||||
// Report to the browser that the payment failed, prompting it to
|
||||
// re-show the payment interface, or show an error message and close
|
||||
// the payment interface.
|
||||
ev.complete('fail');
|
||||
} else {
|
||||
// Report to the browser that the confirmation was successful, prompting
|
||||
// it to close the browser payment method collection interface.
|
||||
ev.complete('success');
|
||||
// Check if the PaymentIntent requires any actions and if so let Stripe.js
|
||||
// handle the flow. If using an API version older than "2019-02-11"
|
||||
// instead check for: `paymentIntent.status === "requires_source_action"`.
|
||||
if (confirmResult.paymentIntent.status === "requires_action") {
|
||||
// Let Stripe.js handle the rest of the payment flow.
|
||||
stripe.confirmCardPayment(clientSecret).then(function(result) {
|
||||
if (result.error) {
|
||||
// The payment failed -- ask your customer for a new payment method.
|
||||
} else {
|
||||
// The payment has succeeded.
|
||||
handleSuccess(result);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// The payment has succeeded.
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
handleSuccess(result) {
|
||||
document.querySelector(
|
||||
'input[name="gateway_response"]'
|
||||
).value = JSON.stringify(result.paymentIntent);
|
||||
|
||||
document.getElementById('server-response').submit();
|
||||
}
|
||||
|
||||
</script>
|
||||
@endpush
|
Loading…
x
Reference in New Issue
Block a user