commit
3f7a61ee61
@ -0,0 +1,19 @@
|
||||
package au.com.royalpay.payment.manage.mappers.shopify;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantAccountRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchantAccount;
|
||||
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_accounts", pkName = "account_id", keyGenerator = Jdbc3KeyGenerator.class)
|
||||
public interface MerchantAccountMapper {
|
||||
|
||||
@AutoSql(SqlType.INSERT)
|
||||
void insert(MerchantAccountRequest accountRequest);
|
||||
|
||||
@AutoSql(SqlType.SELECT)
|
||||
SimpleMerchantAccount selectByUsername(@Param("username") String username);
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package au.com.royalpay.payment.manage.mappers.shopify;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchant;
|
||||
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)
|
||||
SimpleMerchant selectByClientId(@Param("client_id") Integer clientId);
|
||||
|
||||
@AutoSql(SqlType.SELECT)
|
||||
SimpleMerchant selectByMoniker(@Param("client_moniker") String clientMoniker);
|
||||
|
||||
@AutoSql(SqlType.INSERT)
|
||||
void insert(MerchantRequest merchantRequest);
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
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);
|
||||
|
||||
@AutoSql(SqlType.UPDATE)
|
||||
void update(ShopifyStore shopifyStore);
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
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.graphqlclient.PaymentsAppConfigureClient;
|
||||
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.entity.SimpleMerchant;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchantAccount;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.MerchantAccountService;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.MerchantService;
|
||||
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.SignInStatusManager;
|
||||
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ShopifyMerchantAuthApplication {
|
||||
|
||||
@Value("${shopify.version:2021-10}")
|
||||
private String apiVersion;
|
||||
|
||||
@Value("${shopify.auth.apiKey}")
|
||||
private String apiKey;
|
||||
|
||||
private static final String PAYMENT_SETTING_URL = "https://%s/services/payments_partners/gateways/%s/settings";
|
||||
|
||||
@Autowired
|
||||
private ShopifyAuthService shopifyAuthService;
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreService shopifyStoreService;
|
||||
|
||||
@Autowired
|
||||
private SignInStatusManager signInStatusManager;
|
||||
|
||||
@Autowired
|
||||
private MerchantAccountService merchantAccountService;
|
||||
|
||||
@Autowired
|
||||
private MerchantService merchantService;
|
||||
|
||||
@Autowired
|
||||
private PaymentsAppConfigureClient paymentsAppConfigureClient;
|
||||
|
||||
/**
|
||||
* 获取shopify店铺授权URL
|
||||
*
|
||||
* @param request 店铺信息
|
||||
* @return
|
||||
*/
|
||||
public ShopifyPermissionURL shopifyPermission(ShopifyPermissionRequest request) {
|
||||
LoginInfo loginInfo = new LoginInfo();
|
||||
loginInfo.setLoginId(request.getLoginId());
|
||||
loginInfo.setPassword(request.getPassword());
|
||||
|
||||
signInStatusManager.partnerSignIn(loginInfo);
|
||||
SimpleMerchantAccount simpleMerchantAccount = merchantAccountService.getByUsername(request.getLoginId());
|
||||
|
||||
SimpleMerchant simpleMerchant = merchantService.getByClientId(simpleMerchantAccount.getClientId());
|
||||
|
||||
ShopifyStore shopifyShop = shopifyStoreService.getByShopifyShop(request.getShop());
|
||||
if (shopifyShop == null) {
|
||||
shopifyStoreService.createShopifyStore(ShopifyStore.instanceOf(simpleMerchantAccount, simpleMerchant, request.getShop()));
|
||||
return shopifyAuthService.shopifyPermission(request);
|
||||
}
|
||||
|
||||
shopifyStoreService.modifyShopifyStore(shopifyShop
|
||||
.setClientId(simpleMerchantAccount.getClientId())
|
||||
.setClientMoniker(simpleMerchant.getClientMoniker())
|
||||
.setModifyTime(new Date())
|
||||
.setModifier(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);
|
||||
ShopifyStore shopifyStore = shopifyStoreService.getByShopifyShop(shop);
|
||||
if (shopifyStore == null) {
|
||||
throw new BadRequestException("Get access token error");
|
||||
}
|
||||
shopifyStoreService.modifyShopifyStore(shopifyStore.setAccessToken(accessToken.getAccess_token()).setScope(accessToken.getScope()));
|
||||
|
||||
try {
|
||||
paymentsAppConfigureClient.paymentsAppConfigure(shop, true, apiVersion);
|
||||
} catch (IOException e) {
|
||||
log.error(String.format("Shopify store [%s] payment app setting error: %s", shop, e.getMessage()));
|
||||
throw new BadRequestException("Payment app setting error");
|
||||
}
|
||||
|
||||
String redirectUrl = String.format(PAYMENT_SETTING_URL, shop, apiKey);
|
||||
return accessToken.setRedirectUrl(redirectUrl);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@NoArgsConstructor
|
||||
public class ShopifyAccessToken {
|
||||
|
||||
private String access_token;
|
||||
|
||||
private String scope;
|
||||
|
||||
private String redirectUrl;
|
||||
}
|
@ -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,15 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.graphqlclient;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class GraphqlRequestBody {
|
||||
private String query;
|
||||
private Object variables;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.graphqlclient;
|
||||
|
||||
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.shopify.support.GraphqlSchemaReaderUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PaymentsAppConfigureClient {
|
||||
|
||||
private static final String url = "https://%s/payments_apps/api/%s/graphql.json";
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreService shopifyStoreService;
|
||||
|
||||
public void paymentsAppConfigure(String shopDomain, Boolean ready, String apiVersion) throws IOException {
|
||||
|
||||
WebClient webClient = WebClient.builder().build();
|
||||
|
||||
GraphqlRequestBody graphQLRequestBody = new GraphqlRequestBody();
|
||||
|
||||
final String query = GraphqlSchemaReaderUtil.getSchemaFromFileName("paymentsAppConfigure");
|
||||
|
||||
graphQLRequestBody.setQuery(query);
|
||||
PaymentsAppConfigureRequestBody requestBody = new PaymentsAppConfigureRequestBody(shopDomain, ready);
|
||||
graphQLRequestBody.setVariables(requestBody);
|
||||
|
||||
ShopifyStore shopifyStore = shopifyStoreService.getByShopifyShop(shopDomain);
|
||||
JSONObject result = webClient
|
||||
.post()
|
||||
.uri(String.format(url, shopDomain, apiVersion))
|
||||
.header("X-Shopify-Access-Token", shopifyStore.getAccessToken())
|
||||
.bodyValue(graphQLRequestBody)
|
||||
.retrieve()
|
||||
.bodyToMono(JSONObject.class)
|
||||
.block();
|
||||
|
||||
log.info(String.format("retrieve: [%s]", result.toString()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.graphqlclient;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PaymentsAppConfigureRequestBody {
|
||||
|
||||
private String externalHandle;
|
||||
|
||||
private boolean ready;
|
||||
|
||||
public PaymentsAppConfigureRequestBody(String shopDomain, Boolean ready) {
|
||||
this.externalHandle = shopDomain;
|
||||
this.ready = ready;
|
||||
}
|
||||
}
|
@ -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,33 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.web.command;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
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;
|
||||
|
||||
public static ShopifyPermissionRequest instanceOf(CreateShopifyMerchantCommand command) {
|
||||
return ShopifyPermissionRequest.builder()
|
||||
.loginId(command.getPaymentAccount().getLoginId())
|
||||
.password(command.getPaymentAccount().getPassword())
|
||||
.shop(command.getShopifyShop())
|
||||
.build();
|
||||
}
|
||||
}
|
@ -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,59 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.application;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.application.ShopifyMerchantAuthApplication;
|
||||
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.manage.shopify.store.domain.context.MerchantCreateContext;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantAccountRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchant;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.MerchantAccountService;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.service.MerchantService;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.support.PlatformMerchantProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ShopifyStoreApplication {
|
||||
|
||||
@Autowired
|
||||
private MerchantService merchantservice;
|
||||
|
||||
@Autowired
|
||||
private MerchantAccountService merchantAccountService;
|
||||
|
||||
@Autowired
|
||||
private PlatformMerchantProvider platformMerchantProvider;
|
||||
|
||||
@Autowired
|
||||
private ShopifyMerchantAuthApplication shopifyMerchantAuthApplication;
|
||||
|
||||
/**
|
||||
* 检查partnerCode的商户是否存在
|
||||
*
|
||||
* @param partnerCode 商户用户标识
|
||||
* @return
|
||||
*/
|
||||
public Boolean existMerchant(String partnerCode) {
|
||||
return merchantservice.existMerchant(partnerCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* shopify店铺报备、获取shopify店铺授权
|
||||
*
|
||||
* @param command 报备信息
|
||||
* @return 授权链接
|
||||
*/
|
||||
@Transactional
|
||||
public ShopifyPermissionURL register(CreateShopifyMerchantCommand command) {
|
||||
|
||||
MerchantCreateContext merchantCreateContext = new MerchantCreateContext(platformMerchantProvider, command);
|
||||
SimpleMerchant simpleMerchant = merchantservice.createMerchant(merchantCreateContext);
|
||||
|
||||
MerchantAccountRequest accountRequest = MerchantAccountRequest.instanceOf(command, simpleMerchant);
|
||||
merchantAccountService.createAccount(accountRequest);
|
||||
|
||||
return shopifyMerchantAuthApplication.shopifyPermission(ShopifyPermissionRequest.instanceOf(command));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.context;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentAccountCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.support.PlatformMerchantProvider;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentMerchantCommand;
|
||||
import au.com.royalpay.payment.tools.exceptions.BadRequestException;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class MerchantCreateContext {
|
||||
|
||||
private PlatformMerchantProvider platformMerchantProvider;
|
||||
|
||||
private CreateShopifyMerchantCommand command;
|
||||
|
||||
public MerchantCreateContext(PlatformMerchantProvider platformMerchantProvider, CreateShopifyMerchantCommand command) {
|
||||
this.platformMerchantProvider = platformMerchantProvider;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
public String contactPhone() {
|
||||
return command.getPaymentMerchant().getContactPhone();
|
||||
}
|
||||
|
||||
public MerchantRequest genRequest() {
|
||||
PaymentAccountCommand paymentAccount = command.getPaymentAccount();
|
||||
if (!paymentAccount.getPassword().equals(paymentAccount.getConfirmPassword())) {
|
||||
throw new BadRequestException("Inconsistent passwords");
|
||||
}
|
||||
PaymentMerchantCommand paymentMerchant = command.getPaymentMerchant();
|
||||
return MerchantRequest.builder()
|
||||
.clientMoniker(platformMerchantProvider.generateClientMoniker())
|
||||
.companyName(paymentMerchant.getCompanyName())
|
||||
.shortName(paymentMerchant.getCompanyName())
|
||||
.industry("331")
|
||||
.address(paymentMerchant.getAddress())
|
||||
.suburb(paymentMerchant.getSuburb())
|
||||
.postcode(paymentMerchant.getPostcode())
|
||||
.state(paymentMerchant.getState())
|
||||
.country("AUS")
|
||||
.contactPerson(paymentMerchant.getContactPerson())
|
||||
.companyPhone(paymentMerchant.getContactPhone())
|
||||
.contactPhone(paymentMerchant.getContactPhone())
|
||||
.contactEmail(paymentMerchant.getContactEmail())
|
||||
.creator("shopify store")
|
||||
.createTime(new Date())
|
||||
.approveResult(1)
|
||||
.approveTime(new Date())
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentAccountCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentMerchantCommand;
|
||||
import au.com.royalpay.payment.tools.utils.PasswordUtils;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class MerchantAccountRequest {
|
||||
|
||||
private String accountId;
|
||||
|
||||
private Integer clientId;
|
||||
|
||||
private String username;
|
||||
|
||||
private String passwordHash;
|
||||
|
||||
private String salt;
|
||||
|
||||
private String passwordAes;
|
||||
|
||||
private String contactPhone;
|
||||
|
||||
private String contactEmail;
|
||||
|
||||
private String displayName;
|
||||
|
||||
private String creator;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
public static MerchantAccountRequest instanceOf(CreateShopifyMerchantCommand command, SimpleMerchant simpleMerchant) {
|
||||
PaymentMerchantCommand paymentMerchant = command.getPaymentMerchant();
|
||||
PaymentAccountCommand paymentAccount = command.getPaymentAccount();
|
||||
String salt = PasswordUtils.newSalt();
|
||||
String hashPwd = PasswordUtils.hashPwd(paymentAccount.getPassword(), salt);
|
||||
return MerchantAccountRequest.builder()
|
||||
.accountId(UUID.randomUUID().toString())
|
||||
.clientId(simpleMerchant.getClientId())
|
||||
.username(paymentAccount.getLoginId())
|
||||
.salt(salt)
|
||||
.passwordHash(hashPwd)
|
||||
.passwordAes(PasswordUtils.encryptAESPwd(paymentAccount.getPassword()))
|
||||
.contactPhone(paymentMerchant.getContactPhone())
|
||||
.contactEmail(paymentMerchant.getContactEmail())
|
||||
.displayName(paymentAccount.getLoginId())
|
||||
.creator("shopify store")
|
||||
.createTime(new Date())
|
||||
.build();
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class MerchantRequest {
|
||||
|
||||
private Integer clientId;
|
||||
|
||||
private String clientMoniker;
|
||||
|
||||
private String companyName;
|
||||
|
||||
private String shortName;
|
||||
|
||||
private String industry;
|
||||
|
||||
private String address;
|
||||
|
||||
private String suburb;
|
||||
|
||||
private String postcode;
|
||||
|
||||
private String state;
|
||||
|
||||
private String country;
|
||||
|
||||
private String contactPerson;
|
||||
|
||||
private String companyPhone;
|
||||
|
||||
private String contactPhone;
|
||||
|
||||
private String contactEmail;
|
||||
|
||||
private String creator;
|
||||
|
||||
private Date createTime;
|
||||
|
||||
private Integer approveResult;
|
||||
|
||||
private Date approveTime;
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Accessors(chain = true)
|
||||
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;
|
||||
|
||||
private String accessToken;
|
||||
|
||||
private String scope;
|
||||
|
||||
public static ShopifyStore instanceOf(SimpleMerchantAccount merchantAccount, SimpleMerchant simpleMerchant, String shop) {
|
||||
return ShopifyStore.builder()
|
||||
.id(UUID.randomUUID().toString())
|
||||
.clientId(merchantAccount.getClientId())
|
||||
.clientMoniker(simpleMerchant.getClientMoniker())
|
||||
.shopifyShop(shop)
|
||||
.createTime(new Date())
|
||||
.creator("shopify store")
|
||||
.modifyTime(new Date()).build();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SimpleMerchant {
|
||||
private Integer clientId;
|
||||
private String clientMoniker;
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SimpleMerchantAccount {
|
||||
|
||||
private String username;
|
||||
|
||||
private Integer clientId;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.mappers.shopify.MerchantAccountMapper;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantAccountRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchantAccount;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MerchantAccountService {
|
||||
|
||||
@Autowired
|
||||
private MerchantAccountMapper merchantAccountMapper;
|
||||
|
||||
public void createAccount(MerchantAccountRequest accountRequest) {
|
||||
merchantAccountMapper.insert(accountRequest);
|
||||
}
|
||||
|
||||
public SimpleMerchantAccount getByUsername(String username) {
|
||||
return merchantAccountMapper.selectByUsername(username);
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.service;
|
||||
|
||||
import au.com.royalpay.payment.manage.management.sysconfig.core.impls.PermissionPartnerManagerImpl;
|
||||
import au.com.royalpay.payment.manage.mappers.shopify.MerchantMapper;
|
||||
import au.com.royalpay.payment.manage.mappers.system.ClientAccountMapper;
|
||||
import au.com.royalpay.payment.manage.merchants.core.ClientManager;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.context.MerchantCreateContext;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.MerchantRequest;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.entity.SimpleMerchant;
|
||||
import au.com.royalpay.payment.tools.exceptions.ForbiddenException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class MerchantService {
|
||||
|
||||
@Autowired
|
||||
private ClientAccountMapper clientAccountMapper;
|
||||
|
||||
@Autowired
|
||||
private MerchantMapper merchantMapper;
|
||||
|
||||
@Autowired
|
||||
private PermissionPartnerManagerImpl permissionPartnerManager;
|
||||
|
||||
@Autowired
|
||||
private ClientManager clientManager;
|
||||
|
||||
public Boolean existMerchant(String partnerCode) {
|
||||
JSONObject clientInfo = clientManager.getClientInfoByMoniker(partnerCode);
|
||||
if (clientInfo == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public SimpleMerchant createMerchant(MerchantCreateContext merchantCreateContext) {
|
||||
List<JSONObject> account = clientAccountMapper.findByPhone(merchantCreateContext.contactPhone(), "+61");
|
||||
if (account != null && !account.isEmpty()) {
|
||||
throw new ForbiddenException("The user name has been registered");
|
||||
}
|
||||
|
||||
MerchantRequest merchantRequest = merchantCreateContext.genRequest();
|
||||
merchantMapper.insert(merchantRequest);
|
||||
SimpleMerchant simpleMerchant = merchantMapper.selectByMoniker(merchantRequest.getClientMoniker());
|
||||
permissionPartnerManager.permissionClientModuleSave(simpleMerchant.getClientId(), simpleMerchant.getClientMoniker());
|
||||
return simpleMerchant;
|
||||
}
|
||||
|
||||
public SimpleMerchant getByClientId(Integer clientId) {
|
||||
return merchantMapper.selectByClientId(clientId);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
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);
|
||||
|
||||
/**
|
||||
* 变更shopify商户信息
|
||||
*
|
||||
* @param shopifyStore 店铺信息
|
||||
*/
|
||||
void modifyShopifyStore(ShopifyStore shopifyStore);
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void modifyShopifyStore(ShopifyStore shopifyStore) {
|
||||
shopifyStoreMapper.update(shopifyStore);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.web;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL;
|
||||
import au.com.royalpay.payment.manage.shopify.store.domain.application.ShopifyStoreApplication;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
/**
|
||||
* shopify店铺资源
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping(value = "/shopify/store")
|
||||
public class ShopifyStoreController {
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreApplication shopifyStoreApplication;
|
||||
|
||||
/**
|
||||
* 检查loginId的商户是否存在
|
||||
*
|
||||
* @param partnerCode 商户标识
|
||||
*/
|
||||
@GetMapping("/exist")
|
||||
public Boolean validPaymentAppMerchant(@RequestParam("partnerCode") String partnerCode) {
|
||||
return shopifyStoreApplication.existMerchant(partnerCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* shopify店铺报备
|
||||
*
|
||||
* @param command 商户信息
|
||||
* @Return 店铺授权链接
|
||||
*/
|
||||
@PostMapping("/register")
|
||||
public ShopifyPermissionURL createMerchantWithShopify(@RequestBody @Valid CreateShopifyMerchantCommand command) {
|
||||
return shopifyStoreApplication.register(command);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.web.command;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CreateShopifyMerchantCommand {
|
||||
|
||||
private PaymentMerchantCommand paymentMerchant;
|
||||
|
||||
private PaymentAccountCommand paymentAccount;
|
||||
|
||||
@NotBlank(message = "Shop can not blank")
|
||||
private String shopifyShop;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.web.command;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PaymentAccountCommand {
|
||||
|
||||
@NotBlank(message = "LoginId can not blank")
|
||||
private String loginId;
|
||||
|
||||
@NotBlank(message = "Password can not blank")
|
||||
private String password;
|
||||
|
||||
@NotBlank(message = "Confirm password can not blank")
|
||||
private String confirmPassword;
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.web.command;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PaymentMerchantCommand {
|
||||
|
||||
private String companyName;
|
||||
|
||||
private String address;
|
||||
|
||||
private String suburb;
|
||||
|
||||
private String postcode;
|
||||
|
||||
private String state;
|
||||
|
||||
private String country;
|
||||
|
||||
private String contactPerson;
|
||||
|
||||
private String contactPhone;
|
||||
|
||||
private String contactEmail;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package au.com.royalpay.payment.manage.shopify.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GraphqlSchemaReaderUtil {
|
||||
|
||||
public static String getSchemaFromFileName(final String filename) throws IOException {
|
||||
return new String(
|
||||
GraphqlSchemaReaderUtil.class.getClassLoader().getResourceAsStream("graphql/" + filename + ".graphql").readAllBytes());
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package au.com.royalpay.payment.manage.shopify.support;
|
||||
|
||||
import au.com.royalpay.payment.manage.mappers.system.ClientMapper;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Component
|
||||
public class PlatformMerchantProvider {
|
||||
|
||||
@Resource
|
||||
private ClientMapper clientMapper;
|
||||
|
||||
public String generateClientMoniker() {
|
||||
String clientMoniker = RandomStringUtils.random(4, true, true).toUpperCase();
|
||||
JSONObject client = clientMapper.findClientByMoniker(clientMoniker);
|
||||
if (client != null) {
|
||||
generateClientMoniker();
|
||||
}
|
||||
return clientMoniker;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
mutation PaymentsAppConfigure($externalHandle: String, $ready: Boolean!) {
|
||||
paymentsAppConfigure(externalHandle: $externalHandle, ready: $ready) {
|
||||
userErrors{
|
||||
field
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Auth</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/lib/bootstrap/css/bootstrap.min.css">
|
||||
<script type="text/javascript" src="/static/lib/jquery/jquery-2.1.4.min.js"></script>
|
||||
<script type="text/javascript" src="/static/lib/bootstrap/js/bootstrap.min.js"></script>
|
||||
<style>
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.col-centered {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background-color: #ecf0f5">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
<img src="/static/images/pmt_logo_royalpay.png" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 col-centered">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body">
|
||||
<h3 class="text-center m-t-40">
|
||||
This authorization is successful!
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer-container">
|
||||
<div>
|
||||
<span class="footer-font-color"><small>©2015-2021 RoyalPay.</small></span>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript" data-th-inline="javascript">
|
||||
let redirectUrl = /*[[${accessToken.redirectUrl}]]*/'';
|
||||
function redirect() {
|
||||
location.href = redirectUrl;
|
||||
}
|
||||
redirect()
|
||||
</script>
|
||||
|
||||
</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();
|
||||
|
||||
});
|
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
@ -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,239 @@
|
||||
define(['angular', 'uiRouter', 'uiBootstrap'], function (angular) {
|
||||
'use strict';
|
||||
var module = angular.module('shopify.auth', ['ui.router', 'ui.bootstrap', 'ngMessages']);
|
||||
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',
|
||||
params: {'userId': null},
|
||||
controller: 'ShopifyLoginController'
|
||||
}).state('shopify.register', {
|
||||
url: '/register',
|
||||
templateUrl: '/static/shopify/auth/templates/shopify_register.html',
|
||||
params: {'userId': null},
|
||||
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 = {
|
||||
partnerCode: ''
|
||||
}
|
||||
that.authDisable = false
|
||||
that.validStoreLoginId = function () {
|
||||
that.authDisable = true
|
||||
$http.get("/shopify/store/exist", {params: that.store}).then(function (res) {
|
||||
if (res.data) {
|
||||
$state.go('shopify.login', {partnerCode: that.store.partnerCode});
|
||||
} else {
|
||||
$state.go('shopify.register', {partnerCode: that.store.partnerCode});
|
||||
}
|
||||
},function (error) {
|
||||
that.resError = error.data.message;
|
||||
that.authDisable = false
|
||||
})
|
||||
}
|
||||
|
||||
that.registerMerchant = function () {
|
||||
$state.go('shopify.register');
|
||||
}
|
||||
}]);
|
||||
|
||||
module.controller('ShopifyLoginController', ['$scope', '$http', '$stateParams', function ($scope, $http, $stateParams) {
|
||||
var that = $scope;
|
||||
that.model = {
|
||||
shop: '',
|
||||
partnerCode: $stateParams.partnerCode,
|
||||
loginId: '',
|
||||
password: ''
|
||||
}
|
||||
that.loginDisable = false
|
||||
that.activeShopifyMerchant = function () {
|
||||
that.loginDisable = true
|
||||
$http.post("/shopify/auth/permission", that.model).then(function (res) {
|
||||
console.log("permissionUrl", res.data.url)
|
||||
location.href = res.data.url
|
||||
},function (error) {
|
||||
that.resError = error.data.message;
|
||||
that.loginDisable = false
|
||||
})
|
||||
}
|
||||
}]);
|
||||
|
||||
module.controller('ShopifyRegisterController', ['$scope', '$http', '$stateParams', function ($scope, $http, $stateParams) {
|
||||
var that = $scope
|
||||
var stateMap = [
|
||||
{
|
||||
"label": "ACT",
|
||||
"value": "ACT"
|
||||
},
|
||||
{
|
||||
"label": "NSW",
|
||||
"value": "NSW"
|
||||
},
|
||||
{
|
||||
"label": "NT",
|
||||
"value": "NT"
|
||||
},
|
||||
{
|
||||
"label": "QLD",
|
||||
"value": "QLD"
|
||||
},
|
||||
{
|
||||
"label": "SA",
|
||||
"value": "SA"
|
||||
},
|
||||
{
|
||||
"label": "TAS",
|
||||
"value": "TAS"
|
||||
},
|
||||
{
|
||||
"label": "VIC",
|
||||
"value": "VIC"
|
||||
},
|
||||
{
|
||||
"label": "WA",
|
||||
"value": "WA"
|
||||
}
|
||||
];
|
||||
var industryMap = [
|
||||
{
|
||||
"label": "Shoes&Garments",
|
||||
"value": "343"
|
||||
},
|
||||
{
|
||||
"label": "Comprehensive mall",
|
||||
"value": "484"
|
||||
},
|
||||
{
|
||||
"label": "Food",
|
||||
"value": "485"
|
||||
},
|
||||
{
|
||||
"label": "Cosmetics",
|
||||
"value": "486"
|
||||
},
|
||||
{
|
||||
"label": "Maternal and infant",
|
||||
"value": "487"
|
||||
},
|
||||
{
|
||||
"label": "Digital appliance",
|
||||
"value": "488"
|
||||
},
|
||||
{
|
||||
"label": "Logistics",
|
||||
"value": "489"
|
||||
},
|
||||
{
|
||||
"label": "Education Industry",
|
||||
"value": "490"
|
||||
},
|
||||
{
|
||||
"label": "Hotel Industry",
|
||||
"value": "491"
|
||||
},
|
||||
{
|
||||
"label": "Stationery/office supplies",
|
||||
"value": "492"
|
||||
},
|
||||
{
|
||||
"label": "Air Ticket",
|
||||
"value": "493"
|
||||
},
|
||||
{
|
||||
"label": "Other trade industry",
|
||||
"value": "494"
|
||||
}, {
|
||||
"label": "Overseas Education",
|
||||
"value": "528"
|
||||
},
|
||||
{
|
||||
"label": "Travel ticket",
|
||||
"value": "529"
|
||||
},
|
||||
{
|
||||
"label": "Car rental",
|
||||
"value": "530"
|
||||
},
|
||||
{
|
||||
"label": "International Conference",
|
||||
"value": "531"
|
||||
},
|
||||
{
|
||||
"label": "Software",
|
||||
"value": "532"
|
||||
},
|
||||
{
|
||||
"label": "Medical Service",
|
||||
"value": "533"
|
||||
}
|
||||
];
|
||||
that.states = angular.copy(stateMap);
|
||||
that.industries = angular.copy(industryMap);
|
||||
that.partner = {
|
||||
partnerCode: $stateParams.partnerCode
|
||||
};
|
||||
that.registerDisable = false
|
||||
that.saveForm = function (form) {
|
||||
if (form.$invalid) {
|
||||
angular.forEach(form, function (item, key) {
|
||||
if (key.indexOf('$') < 0) {
|
||||
item.$dirty = true;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (that.partner.password != that.partner.password_again) {
|
||||
that.resError = 'Inconsistent passwords';
|
||||
return;
|
||||
}
|
||||
that.registerDisable = true
|
||||
const paymentMerchant = {
|
||||
companyName: that.partner.companyName,
|
||||
address: that.partner.address,
|
||||
suburb: that.partner.suburb,
|
||||
postcode: that.partner.postcode,
|
||||
state: that.partner.state,
|
||||
country: that.partner.country,
|
||||
contactPerson: that.partner.contactPerson,
|
||||
contactPhone: that.partner.contactPhone,
|
||||
contactEmail: that.partner.contactEmail
|
||||
}
|
||||
const paymentAccount = {
|
||||
loginId: that.partner.loginId,
|
||||
password: that.partner.password,
|
||||
confirmPassword: that.partner.password_again
|
||||
}
|
||||
const param = {
|
||||
paymentMerchant,
|
||||
paymentAccount,
|
||||
shopifyShop: that.partner.shopifyShop
|
||||
}
|
||||
$http.post('shopify/store/register', param).then(function (resp) {
|
||||
location.href = resp.data.url
|
||||
}, function (error) {
|
||||
that.resError = error.data.message;
|
||||
that.registerDisable = false
|
||||
});
|
||||
};
|
||||
}]);
|
||||
|
||||
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,49 @@
|
||||
<!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="Partner Code"
|
||||
ng-model="store.partnerCode">
|
||||
</div>
|
||||
<button class="btn btn-warning btn-lg btn-block" ng-disabled="authDisable"
|
||||
ng-click="validStoreLoginId()">Next
|
||||
</button>
|
||||
</form>
|
||||
<div class="m-t-10"></div>
|
||||
<span style="padding-top: 15px">
|
||||
Not a RoyalPay merchant yet, <a href="" ng-click="registerMerchant()">please register</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,119 @@
|
||||
<!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;
|
||||
}
|
||||
|
||||
.col-centered {
|
||||
float: none;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.cu-panel {
|
||||
border: 0px solid transparent !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.cu-panel-body {
|
||||
padding: 25px !important;
|
||||
}
|
||||
|
||||
.cu-panel-nb {
|
||||
border: 0px solid transparent !important;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.pay-method-group {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn-m {
|
||||
margin-right: 10px;
|
||||
width: 120px;
|
||||
border: 1px solid rgba(128, 128, 128, 0.43);
|
||||
}
|
||||
|
||||
.qrcode-container {
|
||||
margin-top: 20px;
|
||||
border-radius: 8px;
|
||||
background-color: #dcdcdc0d;
|
||||
}
|
||||
|
||||
.order-form {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.order-form-item {
|
||||
margin: 10px 20px 10px 0;
|
||||
}
|
||||
|
||||
.order-form-label {
|
||||
color: grey;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.order-form-content {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.order-form-content-lg {
|
||||
font-size: 25px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.col-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
.align-items-center {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
</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 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">
|
||||
This authorization is successful!
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="footer-container">
|
||||
<div>
|
||||
<span class="footer-font-color"><small>©2015-2021 RoyalPay.</small></span>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,53 @@
|
||||
<!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">
|
||||
<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-disabled="loginDisable" ng-click="activeShopifyMerchant()">Log In</button>
|
||||
<div>
|
||||
<p ng-if="resError" style="padding: 6px 12px;font-size: 14px;"
|
||||
class="small text-danger">{{resError}}</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,167 @@
|
||||
<!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-5 col-centered">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-body outer-container">
|
||||
<h3 class="text-center m-t-40" style="margin-bottom: 20px">
|
||||
Register
|
||||
</h3>
|
||||
<form novalidate name="partnerForm" action="" method="post">
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.loginId.$invalid && partnerForm.loginId.$dirty}">
|
||||
<input type="text" class="form-control" ng-model="partner.loginId" name="loginId"
|
||||
placeholder="Login ID" required>
|
||||
<div ng-messages="partnerForm.loginId.$error"
|
||||
ng-if="partnerForm.loginId.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.password.$invalid && partnerForm.password.$dirty}">
|
||||
<input type="password" class="form-control" ng-model="partner.password" name="password"
|
||||
placeholder="Password" required>
|
||||
<div ng-messages="partnerForm.password.$error"
|
||||
ng-if="partnerForm.password.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.password_again.$invalid && partnerForm.password_again.$dirty}">
|
||||
<input type="password" class="form-control" ng-model="partner.password_again" name="password_again"
|
||||
placeholder="Enter the password again" required>
|
||||
<div ng-messages="partnerForm.password_again.$error"
|
||||
ng-if="partnerForm.password_again.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.shopifyShop.$invalid && partnerForm.shopifyShop.$dirty}">
|
||||
<input type="text" class="form-control" ng-model="partner.shopifyShop" name="shopifyShop"
|
||||
placeholder="Shop" required>
|
||||
<p class="help-block">Example: geek-test-shop.myshopify.com</p>
|
||||
<div ng-messages="partnerForm.shopifyShop.$error"
|
||||
ng-if="partnerForm.shopifyShop.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.companyName.$invalid && partnerForm.companyName.$dirty}">
|
||||
<input type="text" class="form-control" ng-model="partner.companyName" name="companyName"
|
||||
placeholder="Store Name /Company Name" required maxlength="15">
|
||||
<div ng-messages="partnerForm.companyName.$error"
|
||||
ng-if="partnerForm.companyName.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.address.$invalid && partnerForm.address.$dirty}">
|
||||
<textarea class="form-control" ng-model="partner.address" placeholder="Address" name="address"
|
||||
required></textarea>
|
||||
<div ng-messages="partnerForm.address.$error"
|
||||
ng-if="partnerForm.address.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.suburb.$invalid && partnerForm.suburb.$dirty}">
|
||||
<input class="form-control" ng-model="partner.suburb" placeholder="Suburb" name="suburb"
|
||||
required >
|
||||
<div ng-messages="partnerForm.suburb.$error"
|
||||
ng-if="partnerForm.suburb.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.postcode.$invalid && partnerForm.postcode.$dirty}">
|
||||
<input class="form-control" ng-model="partner.postcode" placeholder="Postcode"
|
||||
name="postcode"
|
||||
required>
|
||||
<div ng-messages="partnerForm.postcode.$error"
|
||||
ng-if="partnerForm.postcode.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.state.$invalid && partnerForm.state.$dirty}">
|
||||
<select class="form-control" name="state"
|
||||
ng-model="partner.state"
|
||||
id="state-input" required
|
||||
ng-options="state.value as state.label for state in states">
|
||||
<option value="">State</option>
|
||||
</select>
|
||||
<div ng-messages="partnerForm.state.$error"
|
||||
ng-if="partnerForm.state.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.contactPerson.$invalid && partnerForm.contactPerson.$dirty}">
|
||||
<input class="form-control" ng-model="partner.contactPerson" placeholder="Contact Person"
|
||||
required maxlength="50" name="contactPerson">
|
||||
<div ng-messages="partnerForm.contactPerson.$error"
|
||||
ng-if="partnerForm.contactPerson.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.contactPhone.$invalid && partnerForm.contactPhone.$dirty}">
|
||||
<input class="form-control" ng-model="partner.contactPhone" placeholder="Contact Phone"
|
||||
required maxlength="20" name="contactPhone">
|
||||
<div ng-messages="partnerForm.contactPhone.$error"
|
||||
ng-if="partnerForm.contactPhone.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group has-feedback"
|
||||
ng-class="{'has-error':partnerForm.contactEmail.$invalid && partnerForm.contactEmail.$dirty}">
|
||||
<input class="form-control" ng-model="partner.contactEmail" placeholder="Email" required
|
||||
maxlength="50" name="contactEmail">
|
||||
<div ng-messages="partnerForm.contactEmail.$error"
|
||||
ng-if="partnerForm.contactEmail.$dirty">
|
||||
<p class="small text-danger" ng-message="required">Required Field</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 margin-bottom">
|
||||
<button type="button" id="login-btn" class="btn btn-warning btn-block btn-flat btn-lg"
|
||||
ng-disabled="registerDisable" ng-click="saveForm(partnerForm)">Submit
|
||||
</button>
|
||||
<div>
|
||||
<p ng-if="resError" style="padding: 6px 12px;font-size: 14px;"
|
||||
class="small text-danger">{{resError}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,34 @@
|
||||
package au.com.royalpay.payment.manage.shopify.auth.domain.graphqlclient;
|
||||
|
||||
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.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@ActiveProfiles({"dev", "alipay", "bestpay", "jd", "wechat", "rpay", "yeepay", "rppaysvc", "common", "alipayplusaps"})
|
||||
class PaymentsAppConfigureClientTest {
|
||||
|
||||
@Autowired
|
||||
private PaymentsAppConfigureClient paymentsAppConfigureClient;
|
||||
|
||||
@Test
|
||||
public void paymentsAppConfigureClientTest() {
|
||||
|
||||
try {
|
||||
paymentsAppConfigureClient.paymentsAppConfigure("geek-test-shop.myshopify.com", true, "2022-01");
|
||||
} catch (IOException e) {
|
||||
log.error(String.format("PaymentsAppConfigure error: [%s]", e.getMessage()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package au.com.royalpay.payment.manage.shopify.store.domain.application;
|
||||
|
||||
import au.com.royalpay.payment.manage.shopify.auth.domain.entity.ShopifyPermissionURL;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.CreateShopifyMerchantCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentAccountCommand;
|
||||
import au.com.royalpay.payment.manage.shopify.store.web.command.PaymentMerchantCommand;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@ActiveProfiles({"dev", "alipay", "bestpay", "jd", "wechat", "rpay", "yeepay", "rppaysvc", "common", "alipayplusaps"})
|
||||
class ShopifyStoreApplicationTest {
|
||||
|
||||
@Autowired
|
||||
private ShopifyStoreApplication shopifyStoreApplication;
|
||||
|
||||
@Test
|
||||
public void register() {
|
||||
CreateShopifyMerchantCommand command = new CreateShopifyMerchantCommand();
|
||||
|
||||
PaymentMerchantCommand paymentMerchantCommand = new PaymentMerchantCommand();
|
||||
paymentMerchantCommand
|
||||
.setAddress("address")
|
||||
.setCompanyName("company name")
|
||||
.setContactEmail("contact email")
|
||||
.setContactPerson("contact person")
|
||||
.setContactPhone("18014724505")
|
||||
.setCountry("AUS")
|
||||
.setPostcode("post code")
|
||||
.setState("state")
|
||||
.setSuburb("suburb")
|
||||
.setContactEmail("ycfxx521@163.com");
|
||||
|
||||
PaymentAccountCommand accountCommand = new PaymentAccountCommand();
|
||||
accountCommand.setLoginId("alanfeng").setPassword("123456");
|
||||
|
||||
command.setPaymentMerchant(paymentMerchantCommand)
|
||||
.setPaymentAccount(accountCommand)
|
||||
.setShopifyShop("demo.myshopify.com");
|
||||
|
||||
ShopifyPermissionURL shopifyPermissionURL = shopifyStoreApplication.register(command);
|
||||
log.warn(JSON.toJSONString(shopifyPermissionURL));
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modifyShopifyStore() {
|
||||
ShopifyStore shopifyStore = shopifyStoreService.getByShopifyShop("geek-test-shop.myshopify.com");
|
||||
|
||||
shopifyStoreService.modifyShopifyStore(shopifyStore
|
||||
.setClientId(123)
|
||||
.setClientMoniker("hello")
|
||||
.setModifyTime(new Date())
|
||||
.setModifier("geek-test-shop.myshopify.com"));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue