Not able to reach Stripe external payments page when running from localhost:8080 Spring Boot

70 views Asked by At

I am using Angular and Spring Boot. I am able to open a new tab to Stripe's external payment page (test mode) when Angular and Spring Boot are running on separate host. (localhost:4200 and localhost:8080) However, when the Angular files are built and the dist files are placed in Spring Boot's static resource folder (single server), the new tab opens to my home page (default page when the link doesn't exist). Access to other controllers and other parts of my project are working fine.

What happens below is it post a request to server to get a sessionId. After that, window.open will open a new tab to Stripe's external payments page. This works when deployed angular and springboot are running separately.


  async pay(amount: number): Promise<void> {
    this.isLoading = true;
    const payment = {
      name: 'Buy Me a Coffee',
      currency: 'sgd',
      amount: amount,
      quantity: '1',


      //for deployment when single server is used
      successUrl: `${window.location.origin}/api/stripe-success`,
      cancelUrl: `${window.location.origin}/api/stripe-cancelled`,
    
    };

    this.username = this.accountSvc.username

    // setTimeout(() => {
    //   this.router.navigate(['/dashboard', this.username]);
    //   this.isLoading = false;
  
    // }, 3000);

    this.http
    .post(`/api/payment`, payment, { responseType: 'text' })
    .subscribe({
      next: (sessionId: string) => {
        console.log('Session ID:', sessionId);
        
        const url = `/api/checkout/${sessionId}`;
        console.log('the url is ' +url);
        window.open(url, '_blank', 'noopener');


      },
      error: (error: any) => {
        console.error(error);
      }
    });


  }

This is the controller code in Spring Boot. From the logs, the session id and key is received in Angular.


@RestController
@RequestMapping(value = "/api")
// @CrossOrigin(origins = "*")
public class StripeController {

@Value("${stripe.secret.key}")
private String stripeSecretKey;

  @PostMapping("/payment")
  public ResponseEntity<String> paymentWithCheckoutPage(@RequestBody CheckoutPayment payment) throws StripeException {
    // Initialize Stripe and create session parameters
    System.out.println(">>>>>I am inside payment");
    
    Stripe.apiKey = stripeSecretKey;
    
    SessionCreateParams params = SessionCreateParams.builder()
        .addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD)
        .setMode(SessionCreateParams.Mode.PAYMENT)
        .setSuccessUrl(payment.getSuccessUrl())
        .setCancelUrl(payment.getCancelUrl())
        .addLineItem(SessionCreateParams.LineItem.builder()
            .setQuantity(payment.getQuantity())
            .setPriceData(SessionCreateParams.LineItem.PriceData.builder()
                .setCurrency(payment.getCurrency())
                .setUnitAmount(payment.getAmount())
                .setProductData(SessionCreateParams.LineItem.PriceData.ProductData.builder()
                    .setName(payment.getName())
                    .build())
                .build())
            .build())
        .build();

    // Create the Stripe session
    Session session = Session.create(params);

    System.out.println(">>>>I am returning the key>>>>" + session.getId());
    
    // Return the session ID as the response
      return ResponseEntity.ok().body(session.getId());
  }


 @GetMapping("/checkout/{sessionId}")
  public ResponseEntity<String> redirectToCheckout(@PathVariable String sessionId) {

    // Stripe.apiKey = stripeSecretKey;

    System.out.println(">>>the sessionId in checkout is >>>>" + sessionId);
    System.out.println(">>>I am inside checkout/sessionId");
    try {
      // Retrieve the session using the session ID
      Session session = Session.retrieve(sessionId);
      
      // Get the checkout URL from the session
      String checkoutUrl = session.getUrl();
      System.out.println("The checkout Url is >>>>>" + checkoutUrl);
      
      // Redirect to the checkout URL
      return ResponseEntity.status(HttpStatus.FOUND)
          .header(HttpHeaders.LOCATION, checkoutUrl)
          .build();
    } catch (StripeException e) {
      // Handle any errors that occur during the retrieval of the session
      return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
          .body("Error retrieving session");
    }
  }
    


@GetMapping("/stripe-success")
public String stripeSuccess() {
    System.out.println(">> I am inside /stripe-success");

    return "<p>Your payment was successful. Thank you.</p><p>You may close this page.</p>";
}


@GetMapping("/stripe-cancelled")
public String stripeCancelled() {
    System.out.println(">>I am inside /stripe-cancelled");

    return "<p>You have cancelled the transaction.</p><p>You may close this page</p>";
}



}

It fails at window.open(url, '_blank', 'noopener'); where it doesn't seem to access the controller as the logs below are not printed.

    System.out.println(">>>the sessionId in checkout is >>>>" + sessionId);
    System.out.println(">>>I am inside checkout/sessionId");

Some other info which I hope will help:

  1. This is the path at appRoutes.
 { path: 'checkout', component: CheckoutComponent, title: 'Buy me a coffee', canActivate: [loginGuard]},

2. I am using Stripe's test secret key

Will appreciate any advice to solve this. Thank you.

0

There are 0 answers