Have your say in Community Polls: What was/is your greatest motivation to start your own business?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

hmac validation fails for webhooks with credit card info

hmac validation fails for webhooks with credit card info

GeorgeHoffman
Shopify Partner
28 0 4

I am trying to verify hmac for order created webhooks in java springboot application. The validation works for webhooks without credit card information (free due to discounts). For orders with credit card info its coming through with some special characters and hmac validation fails. Below is the relevant code: 

	@PostMapping("/order-create")
	public String orderCreatedWebhook(HttpServletRequest req, HttpServletResponse resp,HttpSession ses, @RequestBody String body){
	        Mac mac = Mac.getInstance("HmacSHA256");
	        mac.init(new SecretKeySpec(secret.getBytes(), HMAC_SHA_256));			
	        byte[] bytes = mac.doFinal(body.getBytes(UTF_8));
	        boolean valid = req.getHeader("X-Shopify-Hmac-SHA256").equals(Base64.encodeBase64String(bytes));	        

 What do I need to do to validate this request. I believe springboot uses UTF-8 by default. Does shopify use some other encoding?

Reply 1 (1)

GeorgeHoffman
Shopify Partner
28 0 4
zuul gateway changes the character encoding to some ISO format ... This seems to fix the issue: final String body = IOUtils.toString(req.getInputStream(),"UTF-8");
 
Posting so others dont need to go through the same pain as me last few days. If you use a spring boot app with or without zuul gateway the below should work for you. IOUtils comes from apache commons. 

 

 

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.io.IOUtils;

@PostMapping("/order-create")
	public String orderCreatedWebhook(HttpServletRequest req, HttpServletResponse resp,HttpSession ses){
	        final String body = IOUtils.toString(req.getInputStream(),"UTF-8");
	        Mac mac = Mac.getInstance("HmacSHA256");
	        mac.init(new SecretKeySpec("mywebhooksecretfromnotificationsettings".getBytes(),"HmacSHA256"));			
	        byte[] bytes = mac.doFinal(body.getBytes(UTF_8));
	        boolean valid = req.getHeader("X-Shopify-Hmac-SHA256").equals(Base64.encodeBase64String(bytes));