Stripe payment api 发送 OPTIONS 请求而不是 POST

问题描述 投票:0回答:1

This is where the payment fails, the options request.


const appearance = {
    theme: 'night',
};

const stripe = Stripe('pk_test_51PccgFRo1v56iAOxEVEimciGkyyLOcjVE98T3rqOHLuvx28QNxI8sfvYN0zwSka8vLRIIIEdkOHorjb5OJUdwhIx00VRs64Seu');

// Set up Stripe Elements
const elements = stripe.elements({appearance: {theme: 'night'}});

const card = elements.create('card' );
card.mount('#payment-element');

document.querySelector("#payment-form").addEventListener("submit", async (event) => {
    event.preventDefault();

    document.getElementById('submit').disabled = true;

    const name = document.querySelector("#name").value;
    const email = document.querySelector("#email").value;

    try {
        // Create the customer by sending data to the server
        const customerResponse = await fetch("http://localhost:4242/create-customer", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({ name, email }),
        });

        console.log(customerResponse);

        // Ensure the response is JSON
        if (!customerResponse.ok) {
            throw new Error("Failed to create customer.");
        }

        const customerData = await customerResponse.json();
        console.log("Customer created:", customerData);

        // Create a token for the card details
        const { token, error } = await stripe.createToken(card);

        if (error) {
            console.error('Error creating token:', error);
            alert('Failed to tokenize card details. Please try again.');
            document.getElementById('submit').disabled = false;
            return;
        }

        // Proceed to initialize the payment process
        await initializePayment(customerData.customerId, token.id);

    } catch (error) {
        document.querySelector("#error-message").textContent = error.message || "Failed to create customer.";
        console.error("Error:", error);
        document.getElementById('submit').disabled = false;
    }
});

async function initializePayment(customerId, tokenId) {
    try {
        // Create the checkout session
        const sessionResponse = await fetch("http://localhost:4242/create-checkout-session", {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                customer: customerId, // Pass the customer ID to backend
                token: tokenId,       // Pass the tokenized card ID to backend
                priceId: 'price_1PfUDSRo1v56iAOxxLORAlv9'
            })
        });

        if (!sessionResponse.ok) {
            const errorData = await sessionResponse.json();
            throw new Error(errorData.message || `Failed to create checkout session.`);
        }

        const sessionData = await sessionResponse.json();
        window.location.href = sessionData.url; // Redirect to the Stripe Checkout or success page

    } catch (error) {
        document.querySelector("#error-message").textContent = error.message || "Failed to process payment.";
        console.error('Error:', error);
    } finally {
        document.getElementById('submit').disabled = false;
    }
}


public class Server {
    private static final Gson gson = new Gson();

    public static void main(String[] args) {
        port(4242);

        options("/*", (request, response) -> {
            String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
            if (accessControlRequestHeaders != null) {
                response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
            }

            String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
            if (accessControlRequestMethod != null) {
                response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
            }

            return "OK";
        });

        before((request, response) -> {
            response.header("Access-Control-Allow-Origin", "*");  // Allow all origins
            response.header("Access-Control-Allow-Headers", "*");
            response.header("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
            response.header("Access-Control-Allow-Credentials", "true");
        });



        // Set Stripe API keys directly in the code
        Stripe.apiKey = "sk_test_yHMt2Vkexample";

        // Domain URL
        String domainUrl = "http://localhost:4242";

        get("/config", (request, response) -> {
            response.type("application/json");

            Map<String, Object> responseData = new HashMap<>();
            responseData.put("publishableKey", "pk_test_51PccgFRo1v56iAOxEVEimciGkyyLOcjVE98T3rqOHLuvx28QNxI8sfvYN0zwSka8vLRIIIEdkOHorjb5OJUdwhIx00VRs64Seu");
            responseData.put("proPrice", "price_1PfUDSRo1v56iAOxxLORAlv9");

            return gson.toJson(responseData);
        });

        // Fetch the Checkout Session to display the JSON result on the success page
        get("/checkout-session", (request, response) -> {
            response.type("application/json");

            String sessionId = request.queryParams("sessionId");
            Session session = Session.retrieve(sessionId);

            return gson.toJson(session);
        });

        post("/create-customer", (request, response) -> {
            response.type("application/json");
            Map<String, Object> requestData = gson.fromJson(request.body(), Map.class);
            String email = (String) requestData.get("email");
            String name = (String) requestData.get("name");

            try {
                CustomerCreateParams params = CustomerCreateParams.builder()
                        .setEmail(email)
                        .setName(name)
                        .build();
                Customer customer = Customer.create(params);

                Map<String, Object> responseData = new HashMap<>();
                responseData.put("customerId", customer.getId());
                responseData.put("email", customer.getEmail());
                responseData.put("name", customer.getName());
                return gson.toJson(responseData);
            } catch (StripeException e) {
                response.status(400);
                Map<String, Object> errorData = new HashMap<>();
                errorData.put("error", e.getMessage());
                return gson.toJson(errorData);
            }
        });

        post("/create-checkout-session", (request, response) -> {
            response.type("application/json");

            // Parse request body as JSON
            Map<String, Object> requestData = gson.fromJson(request.body(), Map.class);

            // Retrieve the priceId from the JSON payload
            String priceId = (String) requestData.get("priceId");

            // Create session parameters
            SessionCreateParams params = new SessionCreateParams.Builder()
                    .setSuccessUrl(domainUrl + "/success.html?session_id={CHECKOUT_SESSION_ID}")
                    .setCancelUrl(domainUrl + "/canceled.html")
                    .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
                    .addLineItem(new SessionCreateParams.LineItem.Builder()
                            .setQuantity(1L)
                            .setPrice(priceId)
                            .build()
                    )
                    .build();

            try {
                Session session = Session.create(params);
                response.status(303); // HTTP 303 See Other
                response.redirect(session.getUrl());
                return ""; // Returning an empty string to indicate no body content
            } catch (Exception e) {
                Map<String, Object> messageData = new HashMap<>();
                messageData.put("message", e.getMessage());
                Map<String, Object> responseData = new HashMap<>();
                responseData.put("error", messageData);
                response.status(400);
                return gson.toJson(responseData);
            }
        });


        post("/customer-portal", (request, response) -> {
            String sessionId = request.queryParams("sessionId");

            // Retrieve the Checkout Session to get the customer ID
            Session checkoutSession;
            try {
                checkoutSession = Session.retrieve(sessionId);
            } catch (Exception e) {
                response.status(400);
                return gson.toJson(Collections.singletonMap("error", "Failed to retrieve session: " + e.getMessage()));
            }

            String customer = checkoutSession.getCustomer();

            // Create a Billing Portal session
            com.stripe.param.billingportal.SessionCreateParams params =
                    new com.stripe.param.billingportal.SessionCreateParams.Builder()
                            .setReturnUrl(domainUrl + "/account") // Redirect to your account page after managing billing
                            .setCustomer(customer)
                            .build();
            com.stripe.model.billingportal.Session portalSession;
            try {
                portalSession = com.stripe.model.billingportal.Session.create(params);
            } catch (Exception e) {
                response.status(400);
                return gson.toJson(Collections.singletonMap("error", "Failed to create billing portal session: " + e.getMessage()));
            }

            // Redirect to the billing portal
            response.redirect(portalSession.getUrl(), 303);
            return "";
        });


        post("/webhook", (request, response) -> {
            String payload = request.body();
            String sigHeader = request.headers("Stripe-Signature");
            String endpointSecret = "your_webhook_secret"; // Replace with your actual webhook secret

            Event event;
            try {
                event = Webhook.constructEvent(payload, sigHeader, endpointSecret);
            } catch (SignatureVerificationException e) {
                response.status(400);
                return gson.toJson(Collections.singletonMap("error", "Invalid signature"));
            }

            // Handle the event
            switch (event.getType()) {
                case "checkout.session.completed":
                    // Handle successful payment
                    System.out.println("Checkout Session completed: " + event.getDataObjectDeserializer().getObject().toString());
                    response.status(200);
                    break;
                case "invoice.payment_succeeded":
                    // Handle successful payment for invoices
                    System.out.println("Invoice payment succeeded: " + event.getDataObjectDeserializer().getObject().toString());
                    response.status(200);
                    break;
                case "invoice.payment_failed":
                    // Handle failed payment for invoices
                    System.out.println("Invoice payment failed: " + event.getDataObjectDeserializer().getObject().toString());
                    response.status(200);
                    break;
                case "customer.subscription.created":
                    // Handle subscription creation
                    System.out.println("Subscription created: " + event.getDataObjectDeserializer().getObject().toString());
                    response.status(200);
                    break;
                case "customer.subscription.deleted":
                    // Handle subscription cancellation
                    System.out.println("Subscription canceled: " + event.getDataObjectDeserializer().getObject().toString());
                    response.status(200);
                    break;
                default:
                    response.status(200);
                    System.out.println("Unhandled event type: " + event.getType());
                    break;
            }

            return "";
        });
    }
}

所以这个错误是在执行initial payment函数时引起的,但是由于AWS的限制,stripe不接受OPTIONS请求,根据我的javascript,我可以做些什么来防止这种情况发生,因为我的应用程序在端口8443上运行。我可以看到客户创建发生在条带上,但无法付款。

javascript java stripe-payments
1个回答
0
投票

您的后端代码尝试立即重定向到 Stripe Checkout URL :

response.status(303); // HTTP 303 See Other
response.redirect(session.getUrl()); 

但是你的前端代码期望从后端获取 JSON 并从中提取 URL 并在 JS 中重定向浏览器本身:

const sessionData = await sessionResponse.json();
window.location.href = sessionData.url; // Redirect to the Stripe Checkout or success page

从服务器使用 HTTP 3xx 进行重定向在 fetch/XHR 上下文中不起作用。

要解决此问题,您应该更改后端代码以返回前端期望的信息。

post("/create-checkout-session", (request, response) -> {
    ...
        Session session = Session.create(params);
        Map<String, String> responseData = new HashMap<>();
        responseData.put("url", session.getUrl());
        return gson.toJson(responseData);
   ...
}});

您的代码还有其他超出范围的问题,例如在同一页面上使用 CardElement 和 Checkout,这有点奇怪。

© www.soinside.com 2019 - 2024. All rights reserved.