mirror of
https://github.com/valitydev/adapter-bank-spring-boot-starter.git
synced 2024-11-06 01:05:20 +00:00
commit
21fa50b2c9
9
pom.xml
9
pom.xml
@ -6,7 +6,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.rbkmoney</groupId>
|
||||
<artifactId>adapter-bank-spring-boot-starter</artifactId>
|
||||
<version>0.0.3-SNAPSHOT</version>
|
||||
<version>0.0.4-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
@ -16,6 +16,7 @@
|
||||
<damsel-utils.version>2.1.9</damsel-utils.version>
|
||||
<damsel.version>1.256-2afe121</damsel.version>
|
||||
<serializer.version>0.6.7</serializer.version>
|
||||
<hellgate-adapter-client.version>2.1.9</hellgate-adapter-client.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -94,6 +95,12 @@
|
||||
<version>${serializer.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.rbkmoney.proxy-libs</groupId>
|
||||
<artifactId>hellgate-adapter-client</artifactId>
|
||||
<version>${hellgate-adapter-client.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
@ -0,0 +1,87 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.config;
|
||||
|
||||
import com.rbkmoney.woody.api.flow.WFlow;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Configuration
|
||||
public class FilterConfiguration {
|
||||
|
||||
public static final String HEALTH = "/actuator/health";
|
||||
|
||||
@Value("${server.rest.port}")
|
||||
private int restPort;
|
||||
|
||||
@Value("/${server.rest.endpoint}/")
|
||||
private String restEndpoint;
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean externalPortRestrictingFilter() {
|
||||
Filter filter = new OncePerRequestFilter() {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
String servletPath = request.getServletPath();
|
||||
if ((request.getLocalPort() == restPort)
|
||||
&& !(servletPath.startsWith(restEndpoint) || servletPath.startsWith(HEALTH))) {
|
||||
response.sendError(404, "Unknown address");
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
};
|
||||
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(filter);
|
||||
filterRegistrationBean.setOrder(-100);
|
||||
filterRegistrationBean.setName("httpPortFilter");
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FilterRegistrationBean woodyFilter() {
|
||||
WFlow wFlow = new WFlow();
|
||||
Filter filter = new OncePerRequestFilter() {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
if ((request.getLocalPort() == restPort)
|
||||
&& request.getServletPath().startsWith(restEndpoint)) {
|
||||
wFlow.createServiceFork(() -> {
|
||||
try {
|
||||
filterChain.doFilter(request, response);
|
||||
} catch (IOException | ServletException e) {
|
||||
sneakyThrow(e);
|
||||
}
|
||||
}).run();
|
||||
return;
|
||||
}
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private <E extends Throwable, T> T sneakyThrow(Throwable t) throws E {
|
||||
throw (E) t;
|
||||
}
|
||||
};
|
||||
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(filter);
|
||||
filterRegistrationBean.setOrder(-50);
|
||||
filterRegistrationBean.setName("woodyFilter");
|
||||
filterRegistrationBean.addUrlPatterns(restEndpoint + "*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.config.properties;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Configuration
|
||||
@ConfigurationProperties("adapter")
|
||||
@Validated
|
||||
public class AdapterProperties {
|
||||
|
||||
@NotEmpty
|
||||
private String url;
|
||||
|
||||
@NotEmpty
|
||||
private String callbackUrl;
|
||||
|
||||
@NotEmpty
|
||||
private String pathCallbackUrl;
|
||||
|
||||
@NotEmpty
|
||||
private String pathRecurrentCallbackUrl;
|
||||
|
||||
@NotEmpty
|
||||
private String tagPrefix;
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.controller;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.Callback;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.serializer.CallbackSerializer;
|
||||
import com.rbkmoney.adapter.helpers.hellgate.HellgateAdapterClient;
|
||||
import com.rbkmoney.adapter.helpers.hellgate.exception.HellgateException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Handler callback 3DS
|
||||
*/
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/${server.rest.endpoint}")
|
||||
public class AdapterController {
|
||||
|
||||
private final HellgateAdapterClient hgClient;
|
||||
private final CallbackSerializer callbackSerializer;
|
||||
|
||||
@PostMapping(value = "term_url")
|
||||
public String receivePaymentIncomingParameters(HttpServletRequest request, HttpServletResponse servletResponse) throws IOException {
|
||||
return processCallback(request, servletResponse, hgClient::processPaymentCallback);
|
||||
}
|
||||
|
||||
@PostMapping(value = "rec_term_url")
|
||||
public String receiveRecurrentIncomingParameters(HttpServletRequest request, HttpServletResponse servletResponse) throws IOException {
|
||||
return processCallback(request, servletResponse, hgClient::processRecurrentTokenCallback);
|
||||
}
|
||||
|
||||
private String processCallback(HttpServletRequest servletRequest, HttpServletResponse servletResponse, BiFunction<String, ByteBuffer, ByteBuffer> hgFunction) throws IOException {
|
||||
String resp = "";
|
||||
Callback callbackObj = callbackSerializer.read(servletRequest);
|
||||
log.info("ProcessCallback {}", callbackObj);
|
||||
try {
|
||||
String tag = callbackObj.getMd();
|
||||
ByteBuffer callback = ByteBuffer.wrap(callbackSerializer.writeByte(callbackObj));
|
||||
ByteBuffer response = hgFunction.apply(tag, callback);
|
||||
resp = new String(response.array(), StandardCharsets.UTF_8);
|
||||
} catch (HellgateException e) {
|
||||
log.warn("Failed handle callback for recurrent", e);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed handle callback for recurrent", e);
|
||||
}
|
||||
if (StringUtils.hasText(callbackObj.getTermUrl())) {
|
||||
servletResponse.sendRedirect(callbackObj.getTermUrl());
|
||||
}
|
||||
log.info("ProcessCallback response {}", resp);
|
||||
return resp;
|
||||
}
|
||||
}
|
@ -1,16 +1,13 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.flow;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.AdapterContext;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.EntryStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.ExitStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.Step;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class DefaultStepResolverImpl implements StepResolver<EntryStateModel, ExitStateModel> {
|
||||
public class DefaultStepResolverImpl implements StepResolver<StateModel, ExitStateModel> {
|
||||
|
||||
@Override
|
||||
public Step resolveEntry(EntryStateModel stateModel) {
|
||||
public Step resolveEntry(StateModel stateModel) {
|
||||
switch (stateModel.getTargetStatus()) {
|
||||
case PROCESSED:
|
||||
return resolveProcessedSteps(stateModel);
|
||||
@ -27,18 +24,18 @@ public class DefaultStepResolverImpl implements StepResolver<EntryStateModel, Ex
|
||||
}
|
||||
}
|
||||
|
||||
private Step resolveProcessedSteps(EntryStateModel stateModel) {
|
||||
private Step resolveProcessedSteps(StateModel stateModel) {
|
||||
if (isNextThreeDs(stateModel)) {
|
||||
return Step.FINISH_THREE_DS;
|
||||
} else if (stateModel.isMakeRecurrent()) {
|
||||
return Step.AUTH_RECURRENT;
|
||||
} else if (stateModel.getRecurrentContext() != null && stateModel.getRecurrentContext().getRecToken() != null) {
|
||||
} else if (stateModel.getRecToken() != null && !stateModel.getRecToken().isEmpty()) {
|
||||
return Step.RECURRENT;
|
||||
}
|
||||
return Step.AUTH;
|
||||
}
|
||||
|
||||
private Step resolveAuthRecurrent(EntryStateModel stateModel) {
|
||||
private Step resolveAuthRecurrent(StateModel stateModel) {
|
||||
AdapterContext adapterContext = stateModel.getAdapterContext();
|
||||
if (adapterContext != null
|
||||
&& (Step.GENERATE_TOKEN_FINISH_THREE_DS.equals(adapterContext.getNextStep())
|
||||
@ -49,7 +46,7 @@ public class DefaultStepResolverImpl implements StepResolver<EntryStateModel, Ex
|
||||
return Step.AUTH_RECURRENT;
|
||||
}
|
||||
|
||||
private static boolean isNextThreeDs(EntryStateModel stateModel) {
|
||||
private static boolean isNextThreeDs(StateModel stateModel) {
|
||||
return stateModel.getAdapterContext() != null && stateModel.getAdapterContext().getNextStep() != null
|
||||
&& (Step.FINISH_THREE_DS.equals(stateModel.getAdapterContext().getNextStep())
|
||||
|| Step.GENERATE_TOKEN_FINISH_THREE_DS.equals(stateModel.getAdapterContext().getNextStep()));
|
||||
@ -58,7 +55,7 @@ public class DefaultStepResolverImpl implements StepResolver<EntryStateModel, Ex
|
||||
@Override
|
||||
public Step resolveExit(ExitStateModel stateModel) {
|
||||
EntryStateModel entryStateModel = stateModel.getEntryStateModel();
|
||||
Step step = entryStateModel.getStep();
|
||||
Step step = entryStateModel.getStateModel().getStep();
|
||||
switch (step) {
|
||||
case AUTH_RECURRENT:
|
||||
if (Step.FINISH_THREE_DS.equals(stateModel.getNextStep())) {
|
||||
|
@ -2,9 +2,10 @@ package com.rbkmoney.adapter.bank.spring.boot.starter.flow;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.EntryStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.ExitStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.StateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.Step;
|
||||
|
||||
public interface StepResolver<T extends EntryStateModel, R extends ExitStateModel> {
|
||||
public interface StepResolver<T extends StateModel, R extends ExitStateModel> {
|
||||
|
||||
Step resolveEntry(T stateModel);
|
||||
|
||||
|
@ -1,44 +1,14 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.model;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.constants.TargetStatus;
|
||||
import com.rbkmoney.damsel.cds.ExpDate;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@ToString(exclude = {"pan", "cvv2", "expMonth", "expYear", "cardHolderName"})
|
||||
public class EntryStateModel {
|
||||
|
||||
private String pan;
|
||||
private Byte expMonth;
|
||||
private Short expYear;
|
||||
private String cvv2;
|
||||
private String cardHolderName;
|
||||
private Long amount;
|
||||
private Short currency;
|
||||
private String currencyCode;
|
||||
private OperationModel operationModel;
|
||||
private StateModel stateModel;
|
||||
private TransactionInfo transactionInfo;
|
||||
|
||||
private String ip;
|
||||
private String email;
|
||||
private String phone;
|
||||
|
||||
private String trxId;
|
||||
private Map<String, String> trxExtra;
|
||||
|
||||
private String refundId;
|
||||
private Long refundAmount;
|
||||
private String invoiceDetails;
|
||||
private RecurrentContext recurrentContext;
|
||||
private TargetStatus targetStatus;
|
||||
private boolean makeRecurrent;
|
||||
private AdapterContext adapterContext;
|
||||
|
||||
private Map<String, String> options;
|
||||
|
||||
private Step step;
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class OperationModel {
|
||||
|
||||
@ToString.Exclude
|
||||
private String pan;
|
||||
@ToString.Exclude
|
||||
private Byte expMonth;
|
||||
@ToString.Exclude
|
||||
private Short expYear;
|
||||
@ToString.Exclude
|
||||
private String cvv2;
|
||||
@ToString.Exclude
|
||||
private String cardHolder;
|
||||
|
||||
private String cryptogram;
|
||||
private String eci;
|
||||
|
||||
private Long amount;
|
||||
private Short currencyCode;
|
||||
private String currencySymbolCode;
|
||||
private String createdAt;
|
||||
|
||||
private String ip;
|
||||
private String email;
|
||||
private String phone;
|
||||
|
||||
private Long refundAmount;
|
||||
private String refundId;
|
||||
private String invoiceDetails;
|
||||
private String callbackUrl;
|
||||
|
||||
private Map<String, String> options;
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.model;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.constants.TargetStatus;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class StateModel {
|
||||
|
||||
private String recToken;
|
||||
private TargetStatus targetStatus;
|
||||
private boolean makeRecurrent;
|
||||
private AdapterContext adapterContext;
|
||||
|
||||
private Step step;
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.model;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class TransactionInfo {
|
||||
|
||||
private String trxId;
|
||||
private Map<String, String> trxExtra;
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.service;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.ExitStateModel;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ThreeDsPropertiesService {
|
||||
|
||||
Map<String, String> initProperties(ExitStateModel exitStateModel);
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.service;
|
||||
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.config.properties.AdapterProperties;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.constants.ThreeDsFields;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.ExitStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.utils.RedirectUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ThreeDsPropertiesServiceImpl implements ThreeDsPropertiesService {
|
||||
|
||||
private final AdapterProperties adapterProperties;
|
||||
|
||||
@Override
|
||||
public Map<String, String> initProperties(ExitStateModel exitStateModel) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(ThreeDsFields.PA_REQ, exitStateModel.getPaReq());
|
||||
params.put(ThreeDsFields.MD, exitStateModel.getMd());
|
||||
params.put(ThreeDsFields.TERM_URL, RedirectUtils.getCallbackUrl(adapterProperties.getCallbackUrl(), adapterProperties.getPathCallbackUrl()));
|
||||
return params;
|
||||
}
|
||||
|
||||
}
|
@ -13,10 +13,18 @@ public class CardDateConverter {
|
||||
return String.format("%1$02d", expDate.getYear() % 100);
|
||||
}
|
||||
|
||||
public static String getYearFromShort(short year) {
|
||||
return String.format("%1$02d", year % 100);
|
||||
}
|
||||
|
||||
public static String getMonthFromExpDate(ExpDate expDate) {
|
||||
return String.format("%02d", expDate.getMonth());
|
||||
}
|
||||
|
||||
public static String getMonthFromByte(byte month) {
|
||||
return String.format("%02d", month);
|
||||
}
|
||||
|
||||
public static BigDecimal getFormattedAmount(long amount) {
|
||||
return new BigDecimal(amount).movePointLeft(2);
|
||||
}
|
||||
|
@ -0,0 +1,60 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.utils;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.codec.binary.Hex;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class SignGenerator {
|
||||
|
||||
public static String prepareDataForHmac(String[] fields, MultiValueMap<String, String> params) {
|
||||
StringBuilder dataHmac = new StringBuilder();
|
||||
Arrays.asList(fields)
|
||||
.forEach(field -> {
|
||||
if (params.get(field) != null
|
||||
&& !params.get(field).isEmpty()
|
||||
&& params.get(field).get(0) != null
|
||||
&& !params.get(field).get(0).isEmpty()
|
||||
) {
|
||||
dataHmac.append(params.get(field).get(0).length());
|
||||
dataHmac.append(params.get(field).get(0));
|
||||
} else {
|
||||
dataHmac.append("-");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return dataHmac.toString();
|
||||
}
|
||||
|
||||
public static String sign(String[] fieldsForSign, MultiValueMap<String, String> params, String key, String algorithm) {
|
||||
String dataHmac = prepareDataForHmac(fieldsForSign, params);
|
||||
String pSign = sign(dataHmac, key, algorithm);
|
||||
return pSign.toUpperCase();
|
||||
}
|
||||
|
||||
public static String sign(String data, String key, String algorithm) {
|
||||
try {
|
||||
byte[] decodedKey = Hex.decodeHex(key.toCharArray());
|
||||
SecretKeySpec keySpec = new SecretKeySpec(decodedKey, algorithm);
|
||||
Mac mac = Mac.getInstance(algorithm);
|
||||
mac.init(keySpec);
|
||||
|
||||
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] signatureBytes = mac.doFinal(dataBytes);
|
||||
|
||||
return new String(new Hex().encode(signatureBytes));
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.config.ErrorMappingConfiguration,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.config.properties.TimerProperties,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.config.properties.AdapterProperties,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.config.FilterConfiguration,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.flow.TargetStatusResolver,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.serializer.AdapterSerializer,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.serializer.CallbackSerializer,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.serializer.RecurrentContextSerializer,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.controller.AdapterController,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.service.ThreeDsPropertiesServiceImpl,\
|
||||
com.rbkmoney.adapter.bank.spring.boot.starter.flow.DefaultStepResolverImpl
|
||||
|
@ -3,6 +3,7 @@ package com.rbkmoney.adapter.bank.spring.boot.starter.flow;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.constants.TargetStatus;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.EntryStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.ExitStateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.StateModel;
|
||||
import com.rbkmoney.adapter.bank.spring.boot.starter.model.Step;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@ -13,33 +14,35 @@ public class DefaultStepResolverImplTest {
|
||||
|
||||
@Test
|
||||
public void resolveEntry() {
|
||||
EntryStateModel entryStateModel = EntryStateModel.builder().
|
||||
targetStatus(TargetStatus.CANCELLED)
|
||||
StateModel stateModel = StateModel.builder()
|
||||
.targetStatus(TargetStatus.CANCELLED)
|
||||
.build();
|
||||
Step step = defaultStepResolver.resolveEntry(entryStateModel);
|
||||
Step step = defaultStepResolver.resolveEntry(stateModel);
|
||||
Assert.assertEquals(Step.CANCEL, step);
|
||||
|
||||
entryStateModel.setTargetStatus(TargetStatus.CAPTURED);
|
||||
step = defaultStepResolver.resolveEntry(entryStateModel);
|
||||
stateModel.setTargetStatus(TargetStatus.CAPTURED);
|
||||
step = defaultStepResolver.resolveEntry(stateModel);
|
||||
Assert.assertEquals(Step.CAPTURE, step);
|
||||
|
||||
entryStateModel.setTargetStatus(TargetStatus.PROCESSED);
|
||||
step = defaultStepResolver.resolveEntry(entryStateModel);
|
||||
stateModel.setTargetStatus(TargetStatus.PROCESSED);
|
||||
step = defaultStepResolver.resolveEntry(stateModel);
|
||||
Assert.assertEquals(Step.AUTH, step);
|
||||
|
||||
entryStateModel.setTargetStatus(TargetStatus.AUTH_RECURRENT);
|
||||
step = defaultStepResolver.resolveEntry(entryStateModel);
|
||||
stateModel.setTargetStatus(TargetStatus.AUTH_RECURRENT);
|
||||
step = defaultStepResolver.resolveEntry(stateModel);
|
||||
Assert.assertEquals(Step.AUTH_RECURRENT, step);
|
||||
|
||||
entryStateModel.setTargetStatus(TargetStatus.REFUNDED);
|
||||
step = defaultStepResolver.resolveEntry(entryStateModel);
|
||||
stateModel.setTargetStatus(TargetStatus.REFUNDED);
|
||||
step = defaultStepResolver.resolveEntry(stateModel);
|
||||
Assert.assertEquals(Step.REFUND, step);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveExit() {
|
||||
EntryStateModel entryStateModel = EntryStateModel.builder()
|
||||
.step(Step.AUTH)
|
||||
.stateModel(StateModel.builder()
|
||||
.step(Step.AUTH)
|
||||
.build())
|
||||
.build();
|
||||
ExitStateModel exitStateModel = ExitStateModel.builder()
|
||||
.entryStateModel(entryStateModel)
|
||||
@ -48,7 +51,8 @@ public class DefaultStepResolverImplTest {
|
||||
Step step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.FINISH_THREE_DS, step);
|
||||
|
||||
entryStateModel.setStep(Step.AUTH_RECURRENT);
|
||||
entryStateModel.setStateModel(StateModel.builder()
|
||||
.step(Step.AUTH_RECURRENT).build());
|
||||
step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.GENERATE_TOKEN_FINISH_THREE_DS, step);
|
||||
|
||||
@ -56,15 +60,18 @@ public class DefaultStepResolverImplTest {
|
||||
step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.GENERATE_TOKEN_CAPTURE, step);
|
||||
|
||||
entryStateModel.setStep(Step.GENERATE_TOKEN_FINISH_THREE_DS);
|
||||
entryStateModel.setStateModel(StateModel.builder()
|
||||
.step(Step.GENERATE_TOKEN_FINISH_THREE_DS).build());
|
||||
step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.GENERATE_TOKEN_CAPTURE, step);
|
||||
|
||||
entryStateModel.setStep(Step.GENERATE_TOKEN_CAPTURE);
|
||||
entryStateModel.setStateModel(StateModel.builder()
|
||||
.step(Step.GENERATE_TOKEN_CAPTURE).build());
|
||||
step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.GENERATE_TOKEN_REFUND, step);
|
||||
|
||||
entryStateModel.setStep(Step.GENERATE_TOKEN_REFUND);
|
||||
entryStateModel.setStateModel(StateModel.builder()
|
||||
.step(Step.GENERATE_TOKEN_REFUND).build());
|
||||
step = defaultStepResolver.resolveExit(exitStateModel);
|
||||
Assert.assertEquals(Step.GENERATE_TOKEN_FINISH, step);
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.rbkmoney.adapter.bank.spring.boot.starter.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SignGeneratorTest {
|
||||
|
||||
public static final String HMAC_SHA_1 = "HmacSHA1";
|
||||
|
||||
@Test
|
||||
public void sign() throws NoSuchAlgorithmException {
|
||||
String test = "511.483USD677144616IT Books. Qty: 217Books Online Inc.14www.sample.com1512345678901234589999999919pgw@mail.sample.com11--142003010515302116F2B2DD7E603A7ADA33https://www.sample.com/shop/reply";
|
||||
|
||||
String s = SignGenerator.sign(test, "00112233445566778899AABBCCDDEEFF", HMAC_SHA_1);
|
||||
Assert.assertEquals("FACC882CA67E109E409E3974DDEDA8AAB13A5E48", s.toUpperCase());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user