parent
a299e9ce41
commit
f441fe9b5e
@ -0,0 +1,18 @@
|
||||
package au.com.royalpay.payment.manage.mappers.shopify;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.AutoSql;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.SqlType;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
||||
|
||||
@AutoMapper(tablename = "shopify_store", pkName = "id", keyGenerator = Jdbc3KeyGenerator.class)
|
||||
public interface ShopifyStoreMapper {
|
||||
|
||||
@AutoSql(SqlType.INSERT)
|
||||
void insert(ShopifyStore shopifyStore);
|
||||
|
||||
@AutoSql(SqlType.SELECT)
|
||||
ShopifyStore selectByShop(@Param("shopify_shop") String shop);
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package au.com.royalpay.payment.manage.mappers.system;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.AutoSql;
|
||||
import com.yixsoft.support.mybatis.autosql.annotations.SqlType;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
||||
|
||||
@AutoMapper(tablename = "sys_clients", pkName = "client_id", keyGenerator = Jdbc3KeyGenerator.class)
|
||||
public interface MerchantMapper {
|
||||
|
||||
@AutoSql(SqlType.SELECT)
|
||||
public JSONObject selectByLoginId(@Param("client_id") String loginId);
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.application;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyAccessToken;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.service.ShopifyAuthService;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.web.command.ShopifyPermissionRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.ShopifyStoreService;
|
||||
import au.com.royalpay.payment.manage.signin.beans.LoginInfo;
|
||||
import au.com.royalpay.payment.manage.signin.core.SignInAccountService;
|
||||
import au.com.royalpay.payment.manage.signin.core.SignInStatusManager;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ShopifyMerchantAuthApplication {
|
||||
|
||||
private static final String redisPrefix = "shopify:accessToken:%s";
|
||||
|
||||
@Autowired
|
||||
private StringRedisTemplate redisTemplate;
|
||||
|
||||
@Autowired
|
||||
private ShopifyAuthService shopifyAuthService;
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreService shopifyStoreService;
|
||||
|
||||
@Autowired
|
||||
private SignInAccountService signInAccountService;
|
||||
|
||||
@Autowired
|
||||
private SignInStatusManager signInStatusManager;
|
||||
|
||||
/**
|
||||
* 获取shopify店铺授权URL
|
||||
*
|
||||
* @param request 店铺信息
|
||||
* @return
|
||||
*/
|
||||
public ShopifyPermissionURL shopifyPermission(ShopifyPermissionRequest request) {
|
||||
LoginInfo loginInfo = new LoginInfo();
|
||||
loginInfo.setLoginId(request.getLoginId());
|
||||
loginInfo.setPassword(request.getPassword());
|
||||
String statusKey = signInStatusManager.partnerSignIn(loginInfo);
|
||||
JSONObject client = signInStatusManager.getCurrentClient(statusKey);
|
||||
|
||||
shopifyStoreService.createShopifyStore(ShopifyStore.instanceOf(client, request.getShop()));
|
||||
return shopifyAuthService.shopifyPermission(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* shopify商户授权
|
||||
*
|
||||
* @param shop shopify商户标识
|
||||
* @param code 授权code
|
||||
* @return
|
||||
*/
|
||||
public ShopifyAccessToken merchantOnboard(String shop, String code) {
|
||||
ShopifyAccessToken accessToken = shopifyAuthService.getAccessToken(shop, code);
|
||||
redisTemplate.boundValueOps(String.format(redisPrefix, shop)).set(accessToken.getAccess_token());
|
||||
return accessToken;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ShopifyAccessToken {
|
||||
|
||||
private String access_token;
|
||||
|
||||
private String scope;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class ShopifyPermissionBackParam {
|
||||
|
||||
@NotBlank(message = "code not blank")
|
||||
private String code;
|
||||
private String hmac;
|
||||
private String host;
|
||||
@NotBlank(message = "shop not blank")
|
||||
private String shop;
|
||||
private String state;
|
||||
private String timestamp;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.entity;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class ShopifyPermissionURL {
|
||||
|
||||
private String url;
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyAccessToken;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.web.command.ShopifyAccessTokenRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.web.command.ShopifyPermissionRequest;
|
||||
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
|
||||
import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ShopifyAuthService {
|
||||
|
||||
@Value("${shopify.auth.apiKey}")
|
||||
private String clientId;
|
||||
|
||||
@Value("${shopify.auth.apiSecretKey}")
|
||||
private String clientSecret;
|
||||
|
||||
@Value("${shopify.auth.scope}")
|
||||
private String scope;
|
||||
|
||||
private static final String PERMISSION_URL = "https://%s/admin/oauth/authorize?client_id=%s&scope=%s&redirect_uri=%s&state=%s&grant_options[]=per-user";
|
||||
|
||||
private static final String ACCESS_TOKEN_URL = "https://%s/admin/oauth/access_token";
|
||||
|
||||
@Autowired
|
||||
@Qualifier("shopifyRestTemplate")
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
public ShopifyPermissionURL shopifyPermission(ShopifyPermissionRequest request) {
|
||||
String redirectUri = PlatformEnvironment.getEnv().concatUrl("/shopify/auth/back");
|
||||
String permissionUrl = String.format(PERMISSION_URL, request.getShop(), clientId, scope, redirectUri, String.valueOf(new Date().getTime()).substring(0,10));
|
||||
return ShopifyPermissionURL.builder().url(permissionUrl).build();
|
||||
}
|
||||
|
||||
public ShopifyAccessToken getAccessToken(String shop, String code) {
|
||||
ShopifyAccessTokenRequest request = new ShopifyAccessTokenRequest(clientId, clientSecret, code);
|
||||
ResponseEntity<ShopifyAccessToken> responseEntity;
|
||||
try {
|
||||
responseEntity = restTemplate.postForEntity(String.format(ACCESS_TOKEN_URL, shop), request, ShopifyAccessToken.class);
|
||||
} catch (RestClientException e) {
|
||||
log.error(String.format("Shopify merchant [%s] get access token error: %s", shop, e.getMessage()));
|
||||
throw new ServerErrorException(e.getMessage());
|
||||
}
|
||||
ShopifyAccessToken shopifyAccessToken = responseEntity.getBody();
|
||||
log.info(String.format("Shopify merchant [%s] access token: %s", shop, shopifyAccessToken));
|
||||
return shopifyAccessToken;
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.web;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.application.ShopifyMerchantAuthApplication;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyAccessToken;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL;
|
||||
import au.com.royalpay.payment.manage.shopify.auth.web.command.ShopifyPermissionRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* shopify认证授权资源
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/shopify/auth")
|
||||
public class ShopifyAuthController {
|
||||
|
||||
@Autowired
|
||||
private ShopifyMerchantAuthApplication shopifyMerchantAuthApplication;
|
||||
|
||||
/**
|
||||
* 获取shopify店铺授权URL
|
||||
*
|
||||
* @param request 店铺信息
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/permission")
|
||||
public ShopifyPermissionURL shopifyPermission(@RequestBody @Valid ShopifyPermissionRequest request) {
|
||||
ShopifyPermissionURL shopifyPermissionURL = shopifyMerchantAuthApplication.shopifyPermission(request);
|
||||
return shopifyPermissionURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* shopify授权回调接口
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/back")
|
||||
public ModelAndView shopifyAuthBack(@RequestParam(value = "code") String code,
|
||||
@RequestParam(name = "hmac", required = false) String hmac,
|
||||
@RequestParam(name = "host", required = false) String host,
|
||||
@RequestParam("shop") String shop,
|
||||
@RequestParam(name = "state", required = false) String state,
|
||||
@RequestParam(name = "timestamp", required = false) String timestamp) {
|
||||
ShopifyAccessToken accessToken = shopifyMerchantAuthApplication.merchantOnboard(shop, code);
|
||||
ModelAndView view = new ModelAndView("shopify/auth_back");
|
||||
view.addObject("accessToken",accessToken);
|
||||
return view;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.web.command;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ShopifyAccessTokenRequest {
|
||||
|
||||
private String client_id;
|
||||
private String client_secret;
|
||||
private String code;
|
||||
|
||||
public ShopifyAccessTokenRequest(String clientId, String clientSecret, String code) {
|
||||
this.client_id = clientId;
|
||||
this.client_secret = clientSecret;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.web.command;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
public class ShopifyPermissionRequest {
|
||||
|
||||
@NotBlank(message = "Shop can not blank")
|
||||
private String shop;
|
||||
|
||||
@NotBlank(message = "Login Id can not blank")
|
||||
private String loginId;
|
||||
|
||||
@NotBlank(message = "Password can not blank")
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package au.com.royalpay.payment.manage.shopify.config;
|
||||
|
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@Configuration
|
||||
public class ShopifyApplicationConfig {
|
||||
|
||||
@Bean
|
||||
@Qualifier("shopifyRestTemplate")
|
||||
public RestTemplate restTemplate() {
|
||||
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
|
||||
fastJsonHttpMessageConverter.setSupportedMediaTypes(ImmutableList.of(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));
|
||||
return new RestTemplateBuilder()
|
||||
.messageConverters(new ByteArrayHttpMessageConverter(),
|
||||
new StringHttpMessageConverter(StandardCharsets.UTF_8),
|
||||
fastJsonHttpMessageConverter)
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ShopifyStore {
|
||||
|
||||
private String id;
|
||||
|
||||
private Integer clientId;
|
||||
|
||||
private String clientMoniker;
|
||||
|
||||
private String shopifyShop;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private String creator;
|
||||
|
||||
private Date modifyTime;
|
||||
|
||||
private String modifier;
|
||||
|
||||
public static ShopifyStore instanceOf(JSONObject client, String shop) {
|
||||
Integer clientId = client.getInteger("client_id");
|
||||
String clientMoniker = client.getString("client_moniker");
|
||||
return ShopifyStore.builder()
|
||||
.id(UUID.randomUUID().toString())
|
||||
.clientId(clientId)
|
||||
.clientMoniker(clientMoniker)
|
||||
.shopifyShop(shop)
|
||||
.createTime(new Date())
|
||||
.creator("shopify")
|
||||
.modifyTime(new Date()).build();
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MerchantService {
|
||||
|
||||
@Autowired
|
||||
private ClientAccountMapper clientAccountMapper;
|
||||
|
||||
public Boolean existMerchant(String loginId) {
|
||||
JSONObject account = clientAccountMapper.findByUsername(loginId);
|
||||
if (account == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PaymentAppMerchantService {
|
||||
|
||||
@Autowired
|
||||
private MerchantService merchantservice;
|
||||
|
||||
/**
|
||||
* 检查loginId的商户是否存在
|
||||
*
|
||||
* @param loginId 商户用户标识
|
||||
* @return
|
||||
*/
|
||||
public Boolean existMerchant(String loginId) {
|
||||
return merchantservice.existMerchant(loginId);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore;
|
||||
|
||||
public interface ShopifyStoreService {
|
||||
|
||||
/**
|
||||
* 关联shopify店铺
|
||||
*
|
||||
* @param shopifyStore 店铺信息
|
||||
*/
|
||||
void createShopifyStore(ShopifyStore shopifyStore);
|
||||
|
||||
/**
|
||||
* 根据shop获取shopify store
|
||||
*
|
||||
* @param shop 店铺标识
|
||||
* @return
|
||||
*/
|
||||
ShopifyStore getByShopifyShop(String shop);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service.impl;
|
||||
|
||||
import au.com.royalpay.payment.manage.mappers.shopify.ShopifyStoreMapper;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.ShopifyStoreService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ShopifyStoreServiceImpl implements ShopifyStoreService {
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreMapper shopifyStoreMapper;
|
||||
|
||||
@Override
|
||||
public void createShopifyStore(ShopifyStore shopifyStore) {
|
||||
shopifyStoreMapper.insert(shopifyStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ShopifyStore getByShopifyShop(String shop) {
|
||||
return shopifyStoreMapper.selectByShop(shop);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.web;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.PaymentAppMerchantService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* shopify店铺资源
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/shopify/store")
|
||||
public class ShopifyStoreController {
|
||||
|
||||
@Autowired
|
||||
private PaymentAppMerchantService paymentAppMerchantService;
|
||||
|
||||
/**
|
||||
* 检查loginId的商户是否存在
|
||||
*
|
||||
* @param loginId 商户用户标识
|
||||
*/
|
||||
@GetMapping("/exist")
|
||||
public Boolean validPaymentAppMerchant(@RequestParam("loginId") String loginId) {
|
||||
return paymentAppMerchantService.existMerchant(loginId);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>授权成功!</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,131 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta charset="UTF-8">
|
||||
<title>RoyalPay</title>
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="ico/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="ico/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="ico/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="ico/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="ico/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="ico/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="ico/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="ico/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="ico/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="ico/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="ico/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="ico/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="ico/favicon-16x16.png">
|
||||
<link rel="manifest" href="ico/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#ffffff">
|
||||
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<!-- Tell the browser to be responsive to screen width -->
|
||||
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
|
||||
<link rel="stylesheet" href="static/css/style.css">
|
||||
|
||||
<link rel="stylesheet" href="static/css/new_partner_dashboard.css">
|
||||
<!-- Bootstrap 3.3.5 -->
|
||||
<link rel="stylesheet" href="static/lib/bootstrap/css/bootstrap.min.css">
|
||||
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">-->
|
||||
<link href="static/lib/font-awesome-4.6.3/css/font-awesome.min.css" rel="stylesheet">
|
||||
<!-- Ionicons -->
|
||||
<link rel="stylesheet" href="static/lib/ioicons-2.0.1/css/ionicons.min.css">
|
||||
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="static/lib/dist/css/AdminLTE.min.css">
|
||||
<!-- AdminLTE Skins. Choose a skin from the css/skins
|
||||
folder instead of downloading all of them to reduce the load. -->
|
||||
<link rel="stylesheet" href="static/lib/dist/css/skins/_all-skins.min.css">
|
||||
<link rel="stylesheet" href="static/css/common.css">
|
||||
<style type="text/css">
|
||||
#topnav {
|
||||
font-family: Arimo, sans-serif;
|
||||
}
|
||||
|
||||
.ng-cloak, [ng-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ng-show {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
@keyframes myfirst {
|
||||
0% {
|
||||
transform: rotateY(1deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotateY(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
div.polaroid {
|
||||
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.rotate_left {
|
||||
position: fixed;
|
||||
width: 200px;
|
||||
margin: 0 -100px;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
z-index: 9999999;
|
||||
}
|
||||
|
||||
.dh {
|
||||
width: 30px;
|
||||
animation: myfirst 1s linear 0s infinite alternate;
|
||||
}
|
||||
|
||||
#help img {
|
||||
z-index: 5;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
border: 3px solid;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
@keyframes redpacket {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
10% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
90% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
95% {
|
||||
transform: rotate(-10deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(20deg);
|
||||
}
|
||||
}
|
||||
|
||||
.redpacket {
|
||||
width: 25px;
|
||||
margin-top: -10px;
|
||||
animation: redpacket 1s cubic-bezier(0.96, -0.02, 0.92, 0.64) 0s infinite alternate;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="static/lib/require.js" data-main="static/boot/shopify-auth-boot"></script>
|
||||
</head>
|
||||
|
||||
<body ng-controller="ShopifyAppCtrl" class="skin-blue sidebar-mini">
|
||||
<div class="wrapper royalpay" ng-cloak>
|
||||
<!-- Content Wrapper. Contains page content -->
|
||||
<div class="content-wrapper" style="margin-left: 0px" ui-view>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ./wrapper -->
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Created by yixian on 2016-06-29.
|
||||
*/
|
||||
require.config({
|
||||
baseUrl: './',
|
||||
waitSeconds: 90,
|
||||
urlArgs: 'bust=' + new Date().getTime(),
|
||||
paths: {
|
||||
jquery: 'static/lib/jquery/jquery-2.1.4.min',
|
||||
uiBootstrap: 'static/lib/angular-plugins/ui-bootstrap-tpls-1.2.4.min',
|
||||
uiRouter: 'static/lib/angular-plugins/angular-ui-router.min',
|
||||
angularChecklist: 'static/lib/angular-plugins/checklist-model',
|
||||
angular: 'static/lib/angularjs/angular.min',
|
||||
angularAnimate: 'static/lib/angularjs/angular-animate.min',
|
||||
angularMessages: 'static/lib/angularjs/angular-messages.min',
|
||||
angularSanitize: 'static/lib/angularjs/angular-sanitize.min',
|
||||
angularLocale: 'static/lib/angularjs/angular-locale_zh-cn',
|
||||
bootSwitch: 'static/lib/bootswitch/bootstrap-switch.min',
|
||||
ngBootSwitch: 'static/lib/angular-plugins/angular-bootstrap-switch.min',
|
||||
ngFileUpload: 'static/lib/ngfileupload/ng-file-upload.min',
|
||||
holder: 'static/lib/holder/holder.min',
|
||||
datetimePicker: 'static/lib/datetime-picker/datetime-picker.min',
|
||||
colorpicker: 'static/lib/colorpicker/js/bootstrap-colorpicker-module.min',
|
||||
qrcode: 'static/lib/jquery/jquery.qrcode.min',
|
||||
sockjs: 'static/lib/websocket/sockjs.min',
|
||||
stomp: 'static/lib/websocket/stomp.min',
|
||||
uiSelect: 'static/lib/angular-plugins/select.min',
|
||||
dragdrop: 'static/lib/angular-plugins/angular-drag-and-drop-lists.min',
|
||||
echarts: 'static/lib/echarts/echarts.common.min',
|
||||
angularEcharts: 'static/commons/angular-echarts',
|
||||
decimal:'static/lib/decimal/decimal.min',
|
||||
jstz: 'static/lib/timezone/jstz-1.0.4.min'
|
||||
},
|
||||
shim: {
|
||||
'angular': {deps: ['jquery','decimal'], exports: 'angular'},
|
||||
'angularLocale': ['angular'],
|
||||
'uiBootstrap': ['angular'],
|
||||
'uiRouter': ['angular'],
|
||||
'uiSelect': ['angular', 'css!static/lib/angular-plugins/select.min'],
|
||||
'angularAnimate': ['angular'],
|
||||
'angularMessages': ['angular'],
|
||||
'angularSanitize': ['angular'],
|
||||
'ngFileUpload': ['angular'],
|
||||
'angularChecklist': ['angular'],
|
||||
'datetimePicker': ['angular'],
|
||||
'ngBootSwitch': ['bootSwitch', 'angular'],
|
||||
'bootSwitch': ['jquery', 'css!static/lib/bootswitch/bootstrap-switch.min'],
|
||||
'qrcode': ['jquery'],
|
||||
'colorpicker': ['angular', 'css!static/lib/colorpicker/css/colorpicker.min'],
|
||||
'holder': ['jquery'],
|
||||
'dragdrop': ['angular']
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
'css': 'static/lib/css.min'
|
||||
}
|
||||
}
|
||||
});
|
||||
var modules = [
|
||||
{path: 'static/boot/shopifyMainApp', module: 'shopifyMainApp'},
|
||||
{path: 'static/shopify/auth/shopify.auth', module: 'shopify.auth'},
|
||||
{path: 'static/shopify/auth/shopify.auth.back', module: 'shopify.auth.back'}
|
||||
];
|
||||
|
||||
require(['angular', 'jquery'], function (angular, $) {
|
||||
function boot() {
|
||||
var paths = [];
|
||||
var moduleNames = [];
|
||||
angular.forEach(modules, function (mod) {
|
||||
paths.push(mod.path);
|
||||
moduleNames.push(mod.module);
|
||||
});
|
||||
require(paths, function () {
|
||||
angular.bootstrap(document.body, moduleNames)
|
||||
});
|
||||
}
|
||||
|
||||
boot();
|
||||
|
||||
});
|
@ -0,0 +1,32 @@
|
||||
define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
|
||||
'use strict';
|
||||
var module = angular.module('shopify.auth.back', ['ui.router', 'ui.bootstrap']);
|
||||
module.config(['$stateProvider', function ($stateProvider) {
|
||||
$stateProvider.state('shopifyAuthBack', {
|
||||
url: '/auth_back',
|
||||
templateUrl: '/static/shopify/auth/templates/shopify_auth_back.html',
|
||||
controller: 'ShopifyAuthBackController'
|
||||
});
|
||||
}]);
|
||||
module.controller('ShopifyAuthBackController',['$scope','$http','$location', function ($scope, $http, $location) {
|
||||
var that = $scope;
|
||||
that.getShopifyStorePermission = function () {
|
||||
var params = {
|
||||
code:$location.search().code,
|
||||
hmac: $location.search().hmac,
|
||||
host: $location.search().host,
|
||||
shop: $location.search().shop,
|
||||
state: $location.search().state,
|
||||
timestamp: $location.search().timestamp
|
||||
}
|
||||
console.log("request data:",params)
|
||||
$http.post("/shopify/auth/back",params).then(function (res) {
|
||||
console.log("permission data:",res.data)
|
||||
})
|
||||
}
|
||||
that.getShopifyStorePermission()
|
||||
|
||||
}]);
|
||||
return module;
|
||||
}
|
||||
)
|
@ -0,0 +1,67 @@
|
||||
define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
|
||||
'use strict';
|
||||
var module = angular.module('shopify.auth', ['ui.router', 'ui.bootstrap']);
|
||||
module.config(['$stateProvider', function ($stateProvider) {
|
||||
$stateProvider.state('shopify', {
|
||||
url: '/shopify',
|
||||
templateUrl: '/static/shopify/auth/templates/auth_root.html',
|
||||
controller: 'ShopifyRootController'
|
||||
}).state('shopify.auth', {
|
||||
url: '/auth',
|
||||
templateUrl: '/static/shopify/auth/templates/shopify_auth.html',
|
||||
controller: 'ShopifyAuthController'
|
||||
}).state('shopify.login', {
|
||||
url: '/login',
|
||||
templateUrl: '/static/shopify/auth/templates/shopify_login.html',
|
||||
controller: 'ShopifyLoginController'
|
||||
}).state('shopify.register', {
|
||||
url: '/register',
|
||||
templateUrl: '/static/shopify/auth/templates/shopify_register.html',
|
||||
controller: 'ShopifyRegisterController'
|
||||
});
|
||||
}]);
|
||||
|
||||
module.controller('ShopifyRootController',['$scope','$http','$state',function ($scope, $http, $state) {
|
||||
if ($state.is('shopify')) {
|
||||
$state.go('shopify.auth')
|
||||
}
|
||||
}])
|
||||
|
||||
module.controller('ShopifyAuthController',['$scope','$http','$state', function ($scope, $http, $state) {
|
||||
var that = $scope;
|
||||
that.store = {
|
||||
loginId: ''
|
||||
}
|
||||
that.validStoreLoginId = function () {
|
||||
$http.get("/shopify/store/exist",{params: that.store}).then(function (res) {
|
||||
if (res.data) {
|
||||
$state.go('shopify.login', {userId: that.store.loginId});
|
||||
}else {
|
||||
$state.go('shopify.register', {userId: that.store.loginId});
|
||||
}
|
||||
})
|
||||
}
|
||||
}]);
|
||||
|
||||
module.controller('ShopifyLoginController',['$scope','$http','$state', function ($scope, $http, $state) {
|
||||
var that = $scope;
|
||||
that.model = {
|
||||
shop: '',
|
||||
loginId: '',
|
||||
password: ''
|
||||
}
|
||||
that.activeShopifyMerchant = function () {
|
||||
$http.post("/shopify/auth/permission",that.model).then(function (res) {
|
||||
console.log("permissionUrl",res.data.url)
|
||||
location.href = res.data.url
|
||||
})
|
||||
}
|
||||
}]);
|
||||
|
||||
module.controller('ShopifyRegisterController',['$scope','$http','$state', function ($scope, $http, $state) {
|
||||
|
||||
}]);
|
||||
|
||||
return module;
|
||||
}
|
||||
)
|
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
|
||||
<style>
|
||||
.footer-container {
|
||||
position:fixed;
|
||||
padding: 10px 0;
|
||||
bottom:0;
|
||||
margin-bottom:0;
|
||||
width:100%;
|
||||
background-color: #fff;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.footer-font-color {
|
||||
color: grey;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<img src="/static/images/pmt_logo_royalpay.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ui-view></div>
|
||||
|
||||
<footer class="footer-container">
|
||||
<div>
|
||||
<span class="footer-font-color"><small>©2015-2021 RoyalPay.</small></span>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
|
||||
<style>
|
||||
.col-centered{
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.outer-container {
|
||||
min-height: 65vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-centered">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body outer-container">
|
||||
<h3 class="text-center m-t-40">
|
||||
Connect a RoyalPay account to start accepting payments on Shopify
|
||||
</h3>
|
||||
|
||||
<h4 class="text-center m-t-20">
|
||||
It's free to connect, whether you have an existing RoyalPay account or want to create a new one.
|
||||
</h4>
|
||||
<div class="m-t-40"></div>
|
||||
<form>
|
||||
<div class="form-group form-group-lg">
|
||||
<input class="form-control input-lg" id="exampleInputEmail" placeholder="Login ID" ng-model="store.loginId">
|
||||
</div>
|
||||
<button class="btn btn-warning btn-lg btn-block" ng-click="validStoreLoginId()">Next</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<h1>auth back</h1>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
|
||||
<style>
|
||||
.col-centered{
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.outer-container {
|
||||
min-height: 65vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-centered">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body outer-container">
|
||||
<h3 class="text-center m-t-40">
|
||||
Login
|
||||
</h3>
|
||||
|
||||
<div class="m-t-40"></div>
|
||||
|
||||
<form>
|
||||
<div class="form-group form-group-lg">
|
||||
<input class="form-control input-lg" id="exampleInputEmail" placeholder="Login ID" ng-model="model.loginId">
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-lg">
|
||||
<!-- <div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</span>
|
||||
</div>-->
|
||||
<input type="password" class="form-control" id="exampleInputPassword" placeholder="Password" ng-model="model.password">
|
||||
</div>
|
||||
|
||||
<div class="form-group form-group-lg">
|
||||
<input class="form-control input-lg" id="shopifyShop" placeholder="Shop" ng-model="model.shop">
|
||||
<p class="help-block">Example: geek-test-shop.myshopify.com</p>
|
||||
</div>
|
||||
<button class="btn btn-warning btn-lg btn-block m-t-40" ng-click="activeShopifyMerchant()">Log In</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
|
||||
<style>
|
||||
.col-centered{
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.outer-container {
|
||||
min-height: 65vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-centered">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body outer-container">
|
||||
<h3 class="text-center m-t-40">
|
||||
Register
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,44 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.ShopifyStore;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Slf4j
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@ActiveProfiles({"dev", "alipay", "bestpay", "jd", "wechat", "rpay", "yeepay", "rppaysvc", "common", "alipayplusaps"})
|
||||
class ShopifyStoreServiceTest {
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreService shopifyStoreService;
|
||||
|
||||
@Test
|
||||
public void createShopifyStore() {
|
||||
ShopifyStore shopifyStore = ShopifyStore.builder()
|
||||
.id(UUID.randomUUID().toString())
|
||||
.clientId(00000001)
|
||||
.clientMoniker("tttttt")
|
||||
.shopifyShop("geek-test-shop.myshopify.com")
|
||||
.createTime(new Date())
|
||||
.creator("shopify")
|
||||
.modifyTime(new Date()).build();
|
||||
shopifyStoreService.createShopifyStore(shopifyStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getByShopifyShop() {
|
||||
ShopifyStore shopifyStore = shopifyStoreService.getByShopifyShop("geek-test-shop.myshopify.com");
|
||||
log.info(JSON.toJSONString(shopifyStore));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue