shopify学习路线

2021-04-28  本文已影响0人  小柠有点萌

shopify学习路线

https://shopify.dev/concepts/apps 了解shopifyApp 以及三种app的区别

https://shopify.dev/tutorials/authenticate-with-oauth shopifyapp安装和认证 并获取access_token

创建一个shopifyApp https://www.shopify.com/partners 点击login登录shopify开发账户

可以查看shopifyApp列表并且创建shopifyapp 开发新项目建议使用public app

public app在正式<u>发布之前</u>是无法被<u>非测试商店</u>安装的

如果正式商店想在发布之前安装app,需要使用customer app

image.png

shopify授权和安装代码可以参考omnipersonalitypublic项目中shopify包下的com.uniprocessing.omnipersonalitypublic.shopify.controller.installcontroller

package com.uniprocessing.omnipersonalitypublic.shopify.controller;

import com.alibaba.fastjson.JSON;

import com.uniprocessing.omnipersonalitypublic.domain.dataobject.ShopDo;
import com.uniprocessing.omnipersonalitypublic.domain.dataobject.ShopSettingDo;
import com.uniprocessing.omnipersonalitypublic.service.ShopService;
import com.uniprocessing.omnipersonalitypublic.service.ShopSettingService;
import com.uniprocessing.omnipersonalitypublic.shopify.service.ImportDataService;
import com.uniprocessing.omnipersonalitypublic.util.HMACSHA256;
import com.uniprocessing.omnipersonalitypublic.util.HttpClientUntil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author DELL
 */
@Controller
@RequestMapping("install")
public class InstallController {

    @Autowired
    private ImportDataService importDataService;
    @Value("${serverUrl}")
    private String serverUrl;
    @Value("${pageUrl}")
    private String pageUrl;
    @Resource
    private ShopService shopService;
    @Resource
    private ShopSettingService shopSettingService;
    @Value("${APIKey}")
    private String apiKey;
    @Value("${APISecretkey}")
    private String apiSecretkey;
    //ToDO 正式上线打开
//    @Value("${server.servlet.context-path}")
    // private String context;
    private String context = "/omniPersonalityUM/";
    @Autowired
    private HttpServletRequest request;
    private Logger logger = LoggerFactory.getLogger(InstallController.class);

    @RequestMapping(value = "install", method = RequestMethod.GET)
    public void install(HttpServletResponse response) throws IOException {
        Map<String, String[]> hashMap = request.getParameterMap();
        Set<String> keySet = hashMap.keySet();
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keySet) {
            if (("hmac").equals(key)) {
                continue;
            }
            String value = hashMap.get(key)[0];
            if (value != null) {
                stringBuilder.append(key);
                stringBuilder.append("=");
                stringBuilder.append(value);
                stringBuilder.append("&");
            }
        }
        stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("&"));
        String message = stringBuilder.toString();
        String shop = hashMap.get("shop")[0];
        String hmac1 = HMACSHA256.sha256_HMAC(message, apiSecretkey);
        String hmac = hashMap.get("hmac")[0];


        if (!hmac1.equals(hmac)) {
            return;
        }
        ShopDo shopDo = shopService.getByMyShopIfyDomain(shop);

        //已安装
        if (shopDo != null && !shopDo.isUninstalled()) {
            Cookie cookieShop = new Cookie("shopId", shopDo.getId() + "");
            cookieShop.setPath(context);
            Cookie timezone = new Cookie("timezone", shopDo.getTimezone().substring(1, 10));
            timezone.setPath(context);
            response.addCookie(cookieShop);
            response.addCookie(timezone);
            response.sendRedirect(pageUrl + "/distHome/index.html");
        }
        //未安装
        else if (shopDo == null) {

            //获取accessToken

            String accessToken = getAccessToken(shop, hashMap);
            //导入数据
            shopDo = importDataService.saveShop(shop, accessToken);
            Long shopId = shopDo.getId();
            importDataService.saveProducts(shop, shopId, accessToken);
            importDataService.createWebHooks(shop, accessToken);
            //全局默认设置
            ShopSettingDo shopSettingDo = new ShopSettingDo();
            shopSettingDo.setShopId(shopId);
            shopSettingService.save(shopSettingDo);
            logger.info(shop + "新店铺安装");
            //放入cookie
            Cookie cookieShop = new Cookie("shopId", shopId + "");
            cookieShop.setPath(context);
            Cookie timezone = new Cookie("timezone", shopDo.getTimezone().substring(1, 10));
            timezone.setPath(context);
            response.addCookie(cookieShop);
            response.addCookie(timezone);
            response.sendRedirect(pageUrl + "/distHome/index.html");

        }
        //再次安装
        else {
            String accessToken = getAccessToken(shop, hashMap);
            Long shopId = shopDo.getId();
            //更新数据
            importDataService.updateShop(shop, accessToken);
            importDataService.saveProducts(shop, shopId, accessToken);
            importDataService.clearWebHook(shop, accessToken);
            importDataService.createWebHooks(shop, accessToken);
            logger.info(shop + "再次安装");
            Cookie cookieShop = new Cookie("shopId", shopId + "");
            cookieShop.setPath(context);
            Cookie timezone = new Cookie("timezone", shopDo.getTimezone().substring(1, 10));
            timezone.setPath(context);
            response.addCookie(cookieShop);
            response.addCookie(timezone);
            response.sendRedirect(pageUrl + "/distHome/index.html");
        }

    }

    /**
     * 授权
     *
     * @param httpServletRequest
     * @return
     */
    @RequestMapping(value = "/authorization", method = RequestMethod.GET)
    public String authorization(HttpServletRequest httpServletRequest) {
        Map<String, String[]> hashMap = httpServletRequest.getParameterMap();
        String shop = hashMap.get("shop")[0];
        String url = "https://" + shop + "/admin/oauth/authorize?client_id=" + apiKey + "&scope=read_orders,read_products,write_script_tags,write_themes,write_online_store_pages&redirect_uri=" + serverUrl + "/install/install";
        return "redirect:" + url;
    }

    /**
     * 根据商店名称获取accessToken
     *
     * @param shop
     * @return
     */
    private String getAccessToken(String shop, Map<String, String[]> parameterMap) {
        String url = "https://" + shop + "/admin/oauth/access_token";
        HashMap<String, String> map = new HashMap<>(4);
        map.put("client_id", apiKey);
        map.put("client_secret", apiSecretkey);
        map.put("code", parameterMap.get("code")[0]);
        String json = JSON.toJSONString(map);
        String accessTokenJson = HttpClientUntil.doPost(url, json, null);
        Map<String, String> parse = (Map<String, String>) JSON.parse(accessTokenJson);
        HashMap<String, String> shopMap = new HashMap<>(3);
        shopMap.put("shop", shop);
        shopMap.put("accessToken", parse.get("access_token"));
        return parse.get("access_token");
    }
}

/authorization(例如:htt ps://prisrv.uniprocessing.com/orderMergeUM/install/authorization) 授权全路径必须要配置到shopifyApp 的App Url中

scope 代表所需要的权限 write 权限包含read权限

参考文档:https://shopify.dev/tutorials/authenticate-with-oauth#step-2-ask-for-permission

重点:

https://shopify.dev/docs/admin-api admin api 提供restful和graphql 两种方式,通过admin api 可以获取商家的店铺数据(例如:商品数据,订单数据,店铺数据 ,还可修改shopify的前台页面(需要相应的权限))

https://shopify.dev/docs/admin-api/rest/reference/events/webhook 创建webhook 之后,每当有店铺更新事件(例如商品添加,订单创建)发生,shopify会向我们的服务器发送对应数据,保证数据的实时更新,不同事件webhook的创建依旧需要对应的admin权限

https://shopify.dev/docs/admin-api/rest/reference/products/smartcollection 商品集合分为两种smart和customer,只有smart集合更新和创建的时候才会触发shopify的集合webhook

https://shopify.dev/docs/themes/ajax-api ajax api 免授权,可以在前台页面(页面路径需要被shopify代理,详情见shopify扩展功能)使用

https://shopify.dev/docs/app-extensions/extension-points shopify扩展功能

https://shopify.dev/concepts/app-store/getting-your-app-approved/app-requirements#a-authentication public app 的要求

ps :代码中有TODO标记的地方,需要按照不同情况进行修改

项目部署位置:

/home/用户名称/server/项目名称

例如 /home/devapp/server/omniBizify

静态资源地址(页面之类的) /home/用户名称/nginx/nginx-omni

例如 /home/devapp/nginx/nginx-omni

上一篇下一篇

猜你喜欢

热点阅读