【问题标题】:How to Receive Webhook from Stripe in Java如何在 Java 中从 Stripe 接收 Webhook
【发布时间】:2014-01-17 23:04:45
【问题描述】:

我正在尝试通过 Stripe Payments 的发布请求接收 webhook。处理它的java方法如下所示:

@ResponseBody
@RequestMapping(    consumes="application/json",
                    produces="application/json",
                    method=RequestMethod.POST,
                    value="stripeWebhookEndpoint")
public String stripeWebhookEndpoint(Event event){

    logger.info("\n\n" + event.toString());

    logger.info("\n\n" + event.getId());

    return null;
}

Stripe 事件 总是返回所有空值:

<com.stripe.model.Event@315899720 id=null> JSON: {
  "id": null,
  "type": null,
  "user_id": null,
  "livemode": null,
  "created": null,
  "data": null,
  "pending_webhooks": null
}

如果方法接收一个字符串,并使用@RequestBody:

@ResponseBody
@RequestMapping(    consumes="application/json",
                    produces="application/json",
                    method=RequestMethod.POST,
                    value="stripeWebhookEndpoint")
public String stripeWebhookEndpoint(@RequestBody String json){

    logger.info(json);

    return null;
}

在这里,它打印没有空值的 json。这是正在打印的请求的一部分:

{
  "created": 1326853478,
  "livemode": false,
  "id": "evt_00000000000000",
  "type": "charge.succeeded",
  "object": "event",
  "request": null,
  "data": {
    "object": {
      "id": "ch_00000000000000",
      "object": "charge",
      "created": 1389985862,
      "livemode": false,
      "paid": true,
      "amount": 2995,
      "currency": "usd",
...
}

但是使用带有 Stripe Event 参数的 @RequestBody 会给出 400: bad syntax。

那么为什么我不能把正确的类型,一个Stripe Event,作为参数呢?

【问题讨论】:

  • 谢谢你的提问,但是可以从条纹中点击localhost url吗?

标签: java json rest stripe-payments webhooks


【解决方案1】:

这就是我所做的:

Java 方法仍将 Event 作为 json 字符串接收。然后我使用了 Stripe 的自定义 gson 适配器并通过以下方式获得了事件:

Event event = Event.gson.fromJson(stripeJsonEvent, Event.class);

其中 stripeJsonEvent 是 webhook 端点接收的 json 字符串。

【讨论】:

  • 从库的 1.25 版本开始,它是 Event.GSON.fromJson(stripeJsonEvent, Event.class);
【解决方案2】:

我一直在寻找相同的答案,所以在查看了他们自己的代码之后,他们实际上是这样做的:

String rawJson = IOUtils.toString(request.getInputStream());
Event event = APIResource.GSON.fromJson(rawJson, Event.class);

APIResource 来自他们的库(我使用的是 1.6.5)

【讨论】:

  • 你好胡安。 +1 用于使用 APIResource。我也有一个关于如何做到这一点的答案。
  • 请求来自哪个包?
  • 如何获取事件对象的子对象的属性。假设我想从事件对象中获取订阅 ID。我无法通过 event.get....() 直接访问它,因为它不可用。
【解决方案3】:
public String stripeWebhookEndpoint(@RequestBody String json, HttpServletRequest request) {         
        String header = request.getHeader("Stripe-Signature");      
        String endpointSecret = "your stripe webhook secret";
        try {
            event = Webhook.constructEvent(json, header, endpointSecret);
            System.err.println(event);
        } catch (SignatureVerificationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         //
         enter code here
      return "";

}

【讨论】:

  • 这是正确的
【解决方案4】:

为了从控制器中抽象出所有反序列化逻辑,我做了以下操作:

创建了一个自定义反序列化器

public class StripeEventDeserializer extends JsonDeserializer<Event> {

    private ObjectMapper mapper;
    
    public StripeEventDeserializer(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public Event deserialize(JsonParser jp, DeserializationContext context) throws IOException {
        ObjectNode root = mapper.readTree(jp);

        Event event = ApiResource.GSON.fromJson(root.toString(), Event.class);
        return event;
    }
}

然后我需要将该反序列化器添加到我的 ObjectMapper 配置中:

SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(Event.class, new StripeEventDeserializer(mapper));
mapper.registerModule(simpleModule);

然后我可以在 Spring 休息控制器上正确使用 @RequestBody

@PostMapping("/webhook")
public void webhook(@RequestBody Event stripeEvent)

【讨论】:

    猜你喜欢
    • 2019-11-29
    • 2022-06-16
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2016-05-04
    • 2020-12-12
    相关资源
    最近更新 更多