首页 > 解决方案 > 重定向到条带后丢失会话数据

问题描述

我正在 Spring MVC 中创建一个带有条带支付集成的食品订购系统。当我试图从之前设置的 webhook 控制器中的会话中获取属性时,我得到了 null。为什么?

最重要的是如何解决它?

编辑:

这是我的支付意图控制器,由 client.js 文件调用,现在我在这里设置会话中的项目,此控制器将条带​​生成的客户端密码 id 返回给 client.js,现在 client.js 调用条带并成功付款,付款确认条带在我的 localhost 端点上向我发送一个带有 charge.succeeded 事件的 webhook。现在要处理该事件,我需要会话属性,但我无法从会话中获取它们,因为它返回 null。

支付意图控制器

@RestController public class PaymentController {
    @PostMapping("/create-payment-intent")
    public CreatePaymentResponse createPaymentIntent(@RequestBody CreatePayment createPayment, 
    HttpServletRequest req)
        throws StripeException {

    HttpSession session = req.getSession();

    ArrayList<String> items = new ArrayList<>();
    JsonItem[] jsonItems = createPayment.getItems();
    for (JsonItem jsonItem : jsonItems) {
        items.add(jsonItem.getItemid());
    }

    session.setAttribute("pnames", items);

    Float amount = Float.parseFloat(createPayment.getAmount());
    System.out.println(amount.longValue() * 100l);
    PaymentIntentCreateParams createParams = new PaymentIntentCreateParams.Builder()
            .setCurrency("INR")
            .setAmount(amount.longValue() * 100L)
            .setDescription("product's amount")
            .build();

    PaymentIntent intent = PaymentIntent.create(createParams);
    CreatePaymentResponse paymentResponse = new CreatePaymentResponse(intent.getClientSecret());
    return paymentResponse;
}
}

这是我的 Webhook 控制器

    @RestController
    public class StripeWebhookController {

    @Autowired
    private FoodhubServiceImpl service;
    
    @Autowired
    private Payment payment;
    
    private String endpointSecret="some endpoint secret";
    
    
    @PostMapping("/foodhub/endpoint")
    public String handleStripeEvents(@RequestBody String payload, @RequestHeader("Stripe-Signature") String sigHeader,HttpServletRequest req) {
        
                HttpSession session = req.getSession();
                
                @SuppressWarnings("unchecked")
                ArrayList<String> arr = (ArrayList<String>) session.getAttribute("pnames");//null
                System.out.println(arr.get(0));//null pointer exception
                
                if(sigHeader == null) {
                    return "";
                }
                
                Event event; 
      
                try {
                    event = Webhook.constructEvent(
                        payload, sigHeader, endpointSecret
                    );
                } catch (SignatureVerificationException e) {
                    // Invalid signature
                    System.out.println("Webhook error while validating signature.");
                    System.out.println(e);
                    return "";
                }
                
            // Deserialize the nested object inside the event
            EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
            StripeObject stripeObject = null;
            if (dataObjectDeserializer.getObject().isPresent()) {
                stripeObject = dataObjectDeserializer.getObject().get();
            } else {
                // Deserialization failed, probably due to an API version mismatch.
                // Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
                // instructions on how to handle this case, or return an error here.
            }
            // Handle the event
            switch (event.getType()) {
                case "payment_intent.succeeded":
                    PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
                    System.out.println("Payment succeeded for   "+paymentIntent.getAmount());
                    System.out.println("payload is : "+payload);
                    handlePaymentIntentSucceeded(paymentIntent);
                    // Then define and call a method to handle the successful payment intent.
                    break;
                default:
                    System.out.println("Unhandled event type: " + event.getType());
                    break;
            }
            return "200";
    }


    private void handlePaymentIntentSucceeded(PaymentIntent paymentIntent) {
        
        //do some stuff here    
    
    }
}

标签: javaspring-mvcsessionstripe-paymentswebhooks

解决方案


生成事件时,Webhook 作为完全独立的POST 请求直接从 Stripe 的webhook 交付服务器交付。您的客户不会以任何方式重定向到此,并且请求不会包含除事件对象之外的任何内容。

您无法像尝试从 webhook 事件中那样获取会话数据。

相反,您可以metadata在创建 Payment Intent ( API ref ) 时进行设置,这metadata将包含在任何 Payment Intent webhook 事件中。


推荐阅读