【问题标题】:PayPal Webhook Verification Java SDKPayPal Webhook 验证 Java SDK
【发布时间】:2020-09-19 16:51:12
【问题描述】:

我目前正在将“PayPal 智能支付按钮”集成到 Web 应用程序中。 传递自定义字段并使用此数据接收 Webhook / 购买确认非常有效。

我在验证收到的 Webhook 时遇到问题。文档很差,导致 mit 进入 v1(已弃用)或 v2 Java SDK,其中没有提及 Webhook 验证。

我在 Java 中集成了以下 SDK。

<dependency>
            <groupId>com.paypal.sdk</groupId>
            <artifactId>checkout-sdk</artifactId>
            <version>1.0.2</version>
        </dependency>

但我无法找到验证 Webhook 的方法。 我是否阅读了某些内容或如何实现 Webhook 验证?

【问题讨论】:

    标签: java spring paypal paypal-webhooks


    【解决方案1】:

    和你有完全相同的问题,这就是为什么我创建了自己的 API 来处理这个问题:https://github.com/Osiris-Team/PayHook

    它使用官方的PayPal-Rest API进行验证,也可以使用第一个SDK中提供的验证方法(离线模式)。

    这是一个将我的 API 与 spring 一起使用的示例:

    @RestController
    @RequestMapping(value = "paypal-hook", method = RequestMethod.POST)
    public class PayHookExample {
    
        // This listens at https://.../paypal-hook
        // for paypal notification messages and returns a "OK" text as response.
        @GetMapping(produces = "text/plain")
        public @ResponseBody String receiveAndRespond(HttpServletRequest request) {
    
            System.out.println("Received webhook event. Validating...");
            try{
                PayHook payHook = new PayHook("INSERT_CLIENT_ID", "INSERT_CLIENT_SECRET");
                payHook.setSandboxMode(true); // Default is false. Remove this in production.
                
                boolean isValid = payHook.isWebhookEventValid("INSERT_VALID_WEBHOOK_ID", // Get it from here: https://developer.paypal.com/developer/applications/
                        Arrays.asList("CHECKOUT.ORDER.APPROVED", "PAYMENTS.PAYMENT.CREATED"), // Insert your valid event types/names here. Full list of all event types/names here: https://developer.paypal.com/docs/api-basics/notifications/webhooks/event-names
                        getHeadersAsMap(request),
                        getBodyAsString(request));
    
                if (isValid) 
                    System.out.println("Webhook-Event is valid!");
                else
                    System.err.println("Webhook-Event is not valid!");
    
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Validation failed: "+e.getMessage());
            }
            return "OK"; // Always return status code 200 with an "OK" text no matter what the result to annoy attackers.
        }
    
        // Simple helper method to help you extract the headers from HttpServletRequest object.
        private Map<String, String> getHeadersAsMap(HttpServletRequest request) {
            Map<String, String> map = new HashMap<String, String>();
            @SuppressWarnings("rawtypes")
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                String value = request.getHeader(key);
                map.put(key, value);
            }
            return map;
        }
    
        // Simple helper method to fetch request data as a string from HttpServletRequest object.
        private String getBodyAsString(HttpServletRequest request) throws IOException {
            StringBuilder stringBuilder = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))){
                String line = "";
                while ((line=reader.readLine())!=null)
                    stringBuilder.append(line);
            }
            return stringBuilder.toString();
        }
    }   @SuppressWarnings("rawtypes")
            Enumeration headerNames = request.getHeaderNames();
            while (headerNames.hasMoreElements()) {
                String key = (String) headerNames.nextElement();
                String value = request.getHeader(key);
                map.put(key, value);
            }
            return map;
        }
    
        // Simple helper method to fetch request data as a string from HttpServletRequest object.
        private String getBodyAsString(HttpServletRequest request) throws IOException {
            StringBuilder stringBuilder = new StringBuilder();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()))){
                String line = "";
                while ((line=reader.readLine())!=null)
                    stringBuilder.append(line);
            }
            return stringBuilder.toString();
        }
    }
    

    希望我能帮上忙, 祝你有美好的一天!

    【讨论】:

      【解决方案2】:

      不支持用于 webhook 集成的 SDK

      (此页面上对旧 SDK 的引用:https://developer.paypal.com/docs/integration/direct/webhooks/rest-webhooks/#verify-event-notifications 已过时)

      所以,你有一些选择。

      最后一个选项实际上是我推荐的。

      这里是您需要的服务器端 SDK:https://github.com/paypal/Checkout-Java-SDK

      这样您将实现两条路线,一条用于“设置交易”(创建订单),另一条用于“捕获交易”(捕获订单)。这里有这些步骤的指南:https://developer.paypal.com/docs/checkout/reference/server-integration/

      然后将连接到这两个服务器端路由的 Web 前端是:https://developer.paypal.com/demo/checkout/#/pattern/server

      使用此服务器端集成时不需要 webhook;在服务器上进行捕获时,您会立即响应成功或失败。

      【讨论】:

      • 感谢您的回答。我想我会切换到服务器端实现。
      猜你喜欢
      • 2016-04-25
      • 2015-06-20
      • 2020-05-25
      • 2020-11-02
      • 2020-07-17
      • 2020-08-22
      • 2021-08-06
      • 2015-07-10
      • 2021-07-26
      相关资源
      最近更新 更多