3

我目前正在将“PayPal Smart Payment Buttons”集成到 WebApp 中。传递自定义字段并使用此数据接收 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 验证?

4

2 回答 2

1

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;在服务器上进行捕获时,您会立即响应成功或失败。

于 2020-06-01T11:51:21.640 回答
0

和你有完全相同的问题,这就是为什么我创建了自己的 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();
    }
}

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

于 2021-04-13T12:13:49.800 回答