Reputation: 2402
I'm using Stripe with django, but while clicking the checkout it return the stripe.error.InvalidRequestError: Request req_N8rlEhXn42Cyxz: Not a valid URL
(due to this question, First i tried my localhost:8000/payment/done then tried it using ngrok so that it could be accessible globaly, but still not working).
it's my settings.py
.....
STRIPE_PUBLIC_KEY = (
"pk_test_51J5kFsFfjIr2jaBwRlGyDJ9McmvvBGclXxkasIGggbh3Fz076sWsGv9z7pSWxy7WuncldIMXDFOq1U3j2bv2Zstu00lMmMnLjD"
)
STRIPE_SECRET_KEY = (
"sk_test_51J5kFsFfjIr2jaBwg1Khel6thuio8gTshaTeIwe0GjqaM57x6XvjZNxQE0udNk8BAVqjjEkCHtFs8KXBEglu2zbR005LkwAzaq"
)
STRIPE_WEBHOOK_SECRET = ""
and my views.py
class CreateCheckOutSessoionView(View):
def post(self, request, *args, **kwargs):
ng = "https://localhost:8000"
product_id = kwargs.get("pk")
product = Product.objects.get(id=product_id)
checkout_session = stripe.checkout.Session.create(
payment_method_types=["card"],
line_items=[
{
"price_data": {
"currency": "usd",
"unit_amount": product.get_cent_price,
"product_data": {
"name": product.name,
"images": [product.image.url],
},
},
"quantity": 1,
},
],
mode="payment",
success_url=ng + "/payment/done",
cancel_url=ng + "/payment/cancel",
)
return JsonResponse({"id": checkout_session.id})
and it's how i'm sending post
to this view
<button type="button" id="checkout-button">Checkout</button>
<script type="text/javascript">
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
// Create an instance of the Stripe object with your publishable API key
var stripe = Stripe("{{ STRIPE_PUBLIC_KEY }}");
var checkoutButton = document.getElementById("checkout-button");
checkoutButton.addEventListener("click", function () {
fetch("{% url 'payment:create-checkout-session' 1 %}", {
method: "POST",
headers: {
'X-CSRFToken': csrftoken,
},
})
.then(function (response) {
return response.json();
})
.then(function (session) {
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function (result) {
// If redirectToCheckout fails due to a browser or network
// error, you should display the localized error message to your
// customer using error.message.
if (result.error) {
alert(result.error.message);
}
})
.catch(function (error) {
console.error("Error:", error);
});
});
</script>
I've no idea on..
Upvotes: 2
Views: 2693
Reputation: 21
I just ran into this issue and was able to fix it, here's what worked for me:
When calling stripe.checkout.Session.create
and passing success_url
and cancel_url
, the method will fail if the URLs are not publicly accessible. If you're working on localhost
, Stripe is unable to verify that the URLs are accessible and the checkout session fails.
Set up a tunnel to make the application URLs publicly accessible without pushing to a staging or production server.
I used a command-line utility called localtunnel
, although there are other options out there (ngrok for instance).
npm install -g localtunnel
from your command lineALLOWED_HOSTS = ['.loca.lt']
CSRF_TRUSTED_ORIGINS = ['http://*.loca.lt', 'https://*.loca.lt']
success_url
and cancel_url
arguments to use that URL. Make sure the subdomain you pick is unique enough to be unlikely to already be in use by another instance of localtunnel. Your code should look something like this:...
baseURL = "https://my-unique-subdomain.loca.lt"
checkout_session = stripe.checkout.Session.create(
...
success_url = baseURL + "/payment/done",
cancel_url = baseURL + "/payment/cancel",
...
lt --subdomain my-unique-subdomain --port 8000
(make sure to replace my-unique-subdomain and 8000 with your own subdomain and port number)https
)Hope that helps!
Upvotes: 2
Reputation: 8727
product.image.url
is a relative URL. It needs to be an absolute URL.
Upvotes: 4