Updates for payment flow

This commit is contained in:
David Bomba 2024-07-01 09:39:40 +10:00
parent a83cb0c3b2
commit 5761f6dc34
4 changed files with 224 additions and 7 deletions

View File

@ -59,7 +59,7 @@ class ProcessPayment extends Component
'frequency_id' => false, 'frequency_id' => false,
'remaining_cycles' => false, 'remaining_cycles' => false,
'is_recurring' => false, 'is_recurring' => false,
'hash' => false, // 'hash' => false,
]; ];
$responder_data = (new LivewireInstantPayment($data))->run(); $responder_data = (new LivewireInstantPayment($data))->run();

View File

@ -274,8 +274,6 @@ class LivewireInstantPayment
if (isset($this->data['hash'])) { if (isset($this->data['hash'])) {
$hash_data['billing_context'] = Cache::get($this->data['hash']); $hash_data['billing_context'] = Cache::get($this->data['hash']);
} elseif ($this->data['hash']) {
$hash_data['billing_context'] = Cache::get($this->data['hash']);
} elseif ($old_hash = PaymentHash::query()->where('fee_invoice_id', $first_invoice->id)->whereNull('payment_id')->orderBy('id', 'desc')->first()) { } elseif ($old_hash = PaymentHash::query()->where('fee_invoice_id', $first_invoice->id)->whereNull('payment_id')->orderBy('id', 'desc')->first()) {
if (isset($old_hash->data->billing_context)) { if (isset($old_hash->data->billing_context)) {
$hash_data['billing_context'] = $old_hash->data->billing_context; $hash_data['billing_context'] = $old_hash->data->billing_context;

View File

@ -1,7 +1,7 @@
<div> <div class="flex flex-col space-y-4 p-4">
@foreach($methods as $index => $method) @foreach($methods as $index => $method)
<button @click="$wire.dispatch('payment-method-selected', { company_gateway_id: {{ $method['company_gateway_id'] }}, gateway_type_id: {{ $method['gateway_type_id'] }}, amount: {{ $amount }} })"> <button class="button button-primary bg-primary" @click="$wire.dispatch('payment-method-selected', { company_gateway_id: {{ $method['company_gateway_id'] }}, gateway_type_id: {{ $method['gateway_type_id'] }}, amount: {{ $amount }} })">
{{ $method['label'] }} {{ $method['label'] }}
</button> </button>

View File

@ -1,4 +1,4 @@
<div> <div class="bg-white">
@if($stripe_account_id) @if($stripe_account_id)
<meta name="stripe-account-id" content="{{ $stripe_account_id }}"> <meta name="stripe-account-id" content="{{ $stripe_account_id }}">
@ -72,6 +72,225 @@
<script src="https://js.stripe.com/v3/"></script> <script src="https://js.stripe.com/v3/"></script>
@endassets @endassets
@vite('resources/js/clients/payments/stripe-credit-card.js') @script
<script>
const publishableKey =
document.querySelector('meta[name="stripe-publishable-key"]')?.content ?? '';
const secret =
document.querySelector('meta[name="stripe-secret"]')?.content ?? '';
const onlyAuthorization =
document.querySelector('meta[name="only-authorization"]')?.content ?? '';
const stripeConnect =
document.querySelector('meta[name="stripe-account-id"]')?.content ?? '';
var cardElement;
var stripe;
var elements;
function setupStripe() {
if (stripeConnect) {
stripe = Stripe(publishableKey, {
stripeAccount: stripeConnect,
});
}
else {
stripe = Stripe(publishableKey);
}
elements = stripe.elements();
}
function createElement() {
cardElement = elements.create('card', {
hidePostalCode: document.querySelector('meta[name=stripe-require-postal-code]')?.content === "0",
value: {
postalCode: document.querySelector('meta[name=client-postal-code]').content,
},
hideIcon: false,
});
}
function mountCardElement() {
cardElement.mount('#card-element');
}
function completePaymentUsingToken() {
let token = document.querySelector('input[name=token]').value;
let payNowButton = document.getElementById('pay-now');
payNowButton = payNowButton;
payNowButton.disabled = true;
payNowButton.querySelector('svg').classList.remove('hidden');
payNowButton.querySelector('span').classList.add('hidden');
stripe
.handleCardPayment(secret, {
payment_method: token,
})
.then((result) => {
if (result.error) {
return handleFailure(result.error.message);
}
return handleSuccess(result);
});
}
function completePaymentWithoutToken() {
let payNowButton = document.getElementById('pay-now');
payNowButton = payNowButton;
payNowButton.disabled = true;
payNowButton.querySelector('svg').classList.remove('hidden');
payNowButton.querySelector('span').classList.add('hidden');
let cardHolderName = document.getElementById('cardholder-name');
stripe
.handleCardPayment(secret, cardElement, {
payment_method_data: {
billing_details: { name: cardHolderName.value },
},
})
.then((result) => {
if (result.error) {
return handleFailure(result.error.message);
}
return handleSuccess(result);
});
}
function handleSuccess(result) {
document.querySelector(
'input[name="gateway_response"]'
).value = JSON.stringify(result.paymentIntent);
let tokenBillingCheckbox = document.querySelector(
'input[name="token-billing-checkbox"]:checked'
);
if (tokenBillingCheckbox) {
document.querySelector('input[name="store_card"]').value =
tokenBillingCheckbox.value;
}
document.getElementById('server-response').submit();
}
function handleFailure(message) {
let errors = document.getElementById('errors');
errors.textContent = '';
errors.textContent = message;
errors.hidden = false;
payNowButton.disabled = false;
payNowButton.querySelector('svg').classList.add('hidden');
payNowButton.querySelector('span').classList.remove('hidden');
}
function handleAuthorization() {
let cardHolderName = document.getElementById('cardholder-name');
let payNowButton = document.getElementById('authorize-card');
payNowButton = payNowButton;
payNowButton.disabled = true;
payNowButton.querySelector('svg').classList.remove('hidden');
payNowButton.querySelector('span').classList.add('hidden');
stripe
.handleCardSetup(secret, cardElement, {
payment_method_data: {
billing_details: { name: cardHolderName.value },
},
})
.then((result) => {
if (result.error) {
return handleFailure(result.error.message);
}
return handleSuccessfulAuthorization(result);
});
}
function handleSuccessfulAuthorization(result) {
document.getElementById('gateway_response').value = JSON.stringify(
result.setupIntent
);
document.getElementById('server_response').submit();
}
setupStripe();
if (onlyAuthorization) {
createElement();
mountCardElement();
document
.getElementById('authorize-card')
.addEventListener('click', () => {
return handleAuthorization();
});
} else {
Array
.from(document.getElementsByClassName('toggle-payment-with-token'))
.forEach((element) => element.addEventListener('click', (element) => {
document.getElementById('stripe--payment-container').classList.add('hidden');
document.getElementById('save-card--container').style.display = 'none';
document.querySelector('input[name=token]').value = element.target.dataset.token;
}));
document
.getElementById('toggle-payment-with-credit-card')
.addEventListener('click', (element) => {
document.getElementById('stripe--payment-container').classList.remove('hidden');
document.getElementById('save-card--container').style.display = 'grid';
document.querySelector('input[name=token]').value = "";
});
createElement();
mountCardElement();
document
.getElementById('pay-now')
.addEventListener('click', () => {
try {
let tokenInput = document.querySelector('input[name=token]');
if (tokenInput.value) {
return completePaymentUsingToken();
}
return completePaymentWithoutToken();
} catch (error) {
console.log(error.message);
}
});
}
</script>
@endscript
</div> </div>