#ginjaninja_api
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! We typically respond in a few minutes, but in some cases we might need a bit more time (e.g., server's busy, you've got a complex question, etc.).
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1253630306209239040
๐ Have more to share? Add details, code, screenshots, videos, etc. below.
hi! any details like a failed request ID req_xxx, screenshots, exact code, stack trace of the error or so on?
what exact code did you write to integrate Google/Apple Pay on this site?
document.addEventListener("DOMContentLoaded", function () {
var stripe = Stripe('{{ env("STRIPE_PUBLIC_KEY") }}');
var elements = stripe.elements();
var priceInPence = {{ $price }};
var paymentRequest = stripe.paymentRequest({
country: 'GB',
currency: 'gbp',
total: {
label: 'Total',
amount: priceInPence,
},
requestPayerName: true,
requestPayerEmail: true,
});
const prButton = elements.create('paymentRequestButton', {
paymentRequest,
});
(async () => {
const result = await paymentRequest.canMakePayment();
if (result) {
prButton.mount('#payment-request-button');
} else {
document.getElementById('payment-request-button').style.display = 'none';
}
})();
style: {
base: {
color: "#133253",
fontSize: "14px",
'::placeholder': {
color: '#133253',
fontSize: '14px',
fontWeight: '600'
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
},
placeholder: 'Card Number',
};
var card = elements.create('cardNumber', cardOptions);
card.mount('#cardNumber');
var expOptions = {
style: {
base: {
color: "#133253",
fontSize: "14px",
'::placeholder': {
color: '#133253',
fontSize: '14px',
fontWeight: '600'
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
},
placeholder: 'Expiry Date',
};```
exp.mount('#cardExpiry');
var cvcOptions = {
style: {
base: {
color: "#133253",
fontSize: "14px",
'::placeholder': {
color: '#133253',
fontSize: '14px',
fontWeight: '600'
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
},
placeholder: 'CVC',
};
var cvc = elements.create('cardCvc', cvcOptions);
cvc.mount('#cardCvc');
var addressOptions = {
style: {
base: {
color: "#133253",
fontSize: "14px",
'::placeholder': {
color: '#133253',
fontSize: '14px',
fontWeight: '600'
}
},
invalid: {
color: "#fa755a",
iconColor: "#fa755a"
}
},
placeholder: 'Postal code',
};
var address = elements.create('postalCode', addressOptions);
address.mount('#postalCode');```
var errorElement = document.getElementById('card-errors');
var submitButton = form.querySelector('button[type="submit"]');
form.addEventListener('submit', function(event) {
event.preventDefault();
submitButton.disabled = true; // Disable the button
submitButton.classList.add('processing'); // Optional: Add processing style
errorElement.textContent = '';
stripe.createPaymentMethod({
type: 'card',
card: card
}).then(function(result) {
if (result.error) {
errorElement.textContent = result.error.message;
submitButton.disabled = false; // Re-enable the button on error
submitButton.classList.remove('processing'); // Optional: Remove processing style
} else {
stripePaymentMethodHandler(result.paymentMethod);
}
}).catch(function(error) {
console.error('Error creating payment method:', error);
submitButton.disabled = false; // Ensure button is re-enabled on error
submitButton.classList.remove('processing'); // Optional: Remove processing style
});
});
function stripePaymentMethodHandler(paymentMethod) {
var paymentMethodInput = document.createElement('input');
paymentMethodInput.setAttribute('type', 'hidden');
paymentMethodInput.setAttribute('name', 'payment_method');
paymentMethodInput.setAttribute('value', paymentMethod.id);
form.appendChild(paymentMethodInput);
form.submit();
}```
<div class="divider">
<span>or</span>
</div>
<form id="payment-form" action="{{ route('send.email') }}" method="POST">
<p class="credit-card">Credit Card <img src="{{asset('images/cards.svg')}}" alt=""></p>
@csrf
<div id="additional-info">
<div id="cardNumber"></div>
<div id="cardExpiry"></div>
<div id="cardCvc"></div>
<div id="postalCode"></div>
<div id="card-errors" role="alert"></div>
<button class="button button-blue" type="submit">Make Payment</button>
<div id="payment-request-button" style="margin-top: 20px;"></div>
</div>
</form>```
you don't seem to have implemented the on('paymentmethod') for the PaymentRequestButton?
step 5 : https://docs.stripe.com/stripe-js/elements/payment-request-button?client=html#complete-payment (you seem to have only done steps 1->3 to mount the button).
event.preventDefault();
submitButton.disabled = true; // Disable the button
submitButton.classList.add('processing'); // Optional: Add processing style
errorElement.textContent = '';
stripe.createPaymentMethod({
type: 'card',
card: card
}).then(function(result) {
if (result.error) {
errorElement.textContent = result.error.message;
submitButton.disabled = false; // Re-enable the button on error
submitButton.classList.remove('processing'); // Optional: Remove processing style
} else {
stripePaymentMethodHandler(result.paymentMethod);
}
}).catch(function(error) {
console.error('Error creating payment method:', error);
submitButton.disabled = false; // Ensure button is re-enabled on error
submitButton.classList.remove('processing'); // Optional: Remove processing style
});
});```
this one
that's not it though
that is just the handler for when your <form> submits. That is not related to the PaymentRequestButton, for which you need a specific listener function.
read the docs I linked please.
$paymentMethodId = $request->input('payment_method');
$paymentIntent = \Stripe\PaymentIntent::create([
'amount' => $request->input('amount'),
'currency' => 'gbp',
'payment_method' => $paymentMethodId,
'confirmation_method' => 'manual',
'confirm' => true,
'return_url' => route('confirmation'),
]);```
you mean this in my controller?
ah ok sorry im alittle lost
yes
ok just to be clear this is for apple pay and google pay only? as anormal card payment works
sorry this will make it easier to read for you
it's for the PaymentRequestButton (which supports Google/Apple Pay) yes. It's step 5 in the guide you presumably were reading to integrate it, you just need to finish writing the code ๐
const prButton = elements.create('paymentRequestButton', {
paymentRequest,
}); so this is not enough
sorry I don't want to keep repeating myself
if it was enough, it would work and you wouldn't have this problem ๐ it's not enough, you need to read the docs fully and write the complete integration as I've mentioned. If you have specific questions about implementing this then let me know as you work on it.
thank you
var stripe = Stripe('{{ env("STRIPE_PUBLIC_KEY") }}');
var elements = stripe.elements();
var priceInPence = {{ $price }};
var clientSecret = '{{ $clientSecret }}';
var paymentRequest = stripe.paymentRequest({
country: 'GB',
currency: 'gbp',
total: {
label: 'Total',
amount: priceInPence,
},
requestPayerName: true,
requestPayerEmail: true,
});
const prButton = elements.create('paymentRequestButton', {
paymentRequest,
});
(async () => {
const result = await paymentRequest.canMakePayment();
if (result) {
prButton.mount('#payment-request-button');
} else {
document.getElementById('payment-request-button').style.display = 'none';
}
})();
paymentRequest.on('paymentmethod', async (ev) => {
const { paymentIntent, error: confirmError } = await stripe.confirmCardPayment(
clientSecret,
{ payment_method: ev.paymentMethod.id },
{ handleActions: false }
);
if (confirmError) {
ev.complete('fail');
} else {
ev.complete('success');
if (paymentIntent.status === "requires_action") {
const { error } = await stripe.confirmCardPayment(clientSecret);
if (error) {
showError("Payment failed. Please try another payment method.");
} else {
showSuccess("Payment successful!");
}
} else {
showSuccess("Payment successful!");
}
}
});``` how are you suppose to handle the client secret becuase i cant pass it untill a payment is made
generally you can create it when the page loads and hold it in a global variable. That's sort of what your code tries to do in that screenshot but you seem to have a bug in how you rendered the template.
alternatively you can make a network call to your backend inside the .on("paymentmethod") function and get the client_secret from that.
thank you