简体   繁体   中英

PayPal Webhook Verification Java SDK

I am currently integrating the "PayPal Smart Payment Buttons" into a WebApp. Passing custom fields and receiving a Webhook / Purchase Confirmation with this data works quite fine.

I am having trouble with validating a received Webhook. The Documentation is poor and leads mit either to v1 (deprecated) or to v2 Java SDK where nothing is mentioned about Webhook verification.

I integrated the following SDK in Java.

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

But I am not able to find a way to verify a Webhook. Did I read over something or how can I achieve the Webhook verification?

There is no supported SDK for webhook integration

(The references to old SDKs on this page: https://developer.paypal.com/docs/integration/direct/webhooks/rest-webhooks/#verify-event-notifications are out of date)

So, you have some choices.

The last option is actually what I would recommend.

Here is the server-side SDK you need: https://github.com/paypal/Checkout-Java-SDK

With that you would implement two routes, one for "Set Up Transaction" (create order), and one for "Capture Transaction" (capture the order). There is a guide for these steps here: https://developer.paypal.com/docs/checkout/reference/server-integration/

The web front-end that will then connect to those two server-side routes is: https://developer.paypal.com/demo/checkout/#/pattern/server

There is no need for webhooks when using this server-side integration; you have an immediate response of success or failure when doing the capture on the server.

Had exactly the same issue as you, thats why I created my own API for handling that: https://github.com/Osiris-Team/PayHook

It's using the official validation methods provided in the first SDK.

Here is an example using my API with 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 at .../paypal-hook/...");
        try{
            PayHook payHook = new PayHook();
            payHook.setSandboxMode(true); // Default is false. Remove this in production.
            
            // Get the header and body
            WebhookEventHeader header = payHook.parseAndGetHeader(getHeadersAsMap(request));
            JsonObject         body   = payHook.parseAndGetBody(getBodyAsString(request));

            // Create this event
            WebhookEvent event = new WebhookEvent(
                    "insert your valid webhook id here", // 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
                    header,
                    body);

            // Do event validation
            payHook.validateWebhookEvent(event); 
            System.out.println("Validation successful!");

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Validation failed: "+e.getMessage());
        }
        return "OK";
    }

    // 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();
    }
}

Hope I could help, have a nice day!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM