PayPal Webhook 验证 Java SDK

PayPal Webhook Verification Java SDK

我目前正在将 "PayPal Smart Payment Buttons" 集成到 WebApp 中。 使用此数据传递自定义字段并接收 Webhook / 购买确认非常有效。

我在验证收到的 Webhook 时遇到问题。文档很差,导致 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 验证?

没有支持 webhook 集成的 SDK

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

所以,你有一些选择。

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

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

有了它,您将实现两条路线,一条用于 "Set Up Transaction"(创建订单),另一条用于 "Capture Transaction"(捕获订单)。这里有这些步骤的指南:https://developer.paypal.com/docs/checkout/reference/server-integration/

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

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

遇到了与您完全相同的问题,这就是为什么我创建了自己的 API 来处理该问题:https://github.com/Osiris-Team/PayHook

使用官方的PayPal-RestAPI验证,也可以使用第一个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();
    }
}

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