mirror of
https://github.com/valitydev/adapter-flow-lib.git
synced 2024-11-06 00:05:22 +00:00
Add flow for work with qr code (#69)
This commit is contained in:
parent
23c1665f0e
commit
94418ab4ea
2
pom.xml
2
pom.xml
@ -12,7 +12,7 @@
|
||||
</parent>
|
||||
|
||||
<artifactId>adapter-flow-lib</artifactId>
|
||||
<version>0.1.25</version>
|
||||
<version>0.2.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>adapter-flow-lib</name>
|
||||
|
@ -4,14 +4,17 @@ import dev.vality.adapter.common.cds.CdsStorageClient;
|
||||
import dev.vality.adapter.common.cds.model.CardDataProxyModel;
|
||||
import dev.vality.adapter.common.damsel.ProxyProviderPackageCreators;
|
||||
import dev.vality.adapter.common.damsel.ProxyProviderPackageExtractors;
|
||||
import dev.vality.adapter.flow.lib.constant.*;
|
||||
import dev.vality.adapter.flow.lib.constant.MetaData;
|
||||
import dev.vality.adapter.flow.lib.constant.OptionFields;
|
||||
import dev.vality.adapter.flow.lib.constant.Step;
|
||||
import dev.vality.adapter.flow.lib.constant.TargetStatus;
|
||||
import dev.vality.adapter.flow.lib.model.*;
|
||||
import dev.vality.adapter.flow.lib.serde.TemporaryContextDeserializer;
|
||||
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
|
||||
import dev.vality.adapter.flow.lib.service.CardDataService;
|
||||
import dev.vality.adapter.flow.lib.service.IdGenerator;
|
||||
import dev.vality.adapter.flow.lib.service.TemporaryContextService;
|
||||
import dev.vality.adapter.flow.lib.utils.AdapterProperties;
|
||||
import dev.vality.adapter.flow.lib.service.CallbackUrlExtractor;
|
||||
import dev.vality.adapter.flow.lib.utils.CardDataUtils;
|
||||
import dev.vality.adapter.flow.lib.utils.TargetStatusResolver;
|
||||
import dev.vality.cds.storage.Auth3DS;
|
||||
@ -55,7 +58,8 @@ public class CtxToEntryModelConverter implements Converter<PaymentContext, Entry
|
||||
MobilePaymentData mobilePaymentData = null;
|
||||
if (paymentResource.isSetDisposablePaymentResource()
|
||||
&& currentStep == null
|
||||
&& targetStatus == TargetStatus.PROCESSED) {
|
||||
&& targetStatus == TargetStatus.PROCESSED
|
||||
&& paymentResource.getDisposablePaymentResource().getPaymentTool().isSetBankCard()) {
|
||||
SessionData sessionData = cdsStorageClient.getSessionData(context);
|
||||
cardData = initCardData(context, paymentResource, sessionData);
|
||||
mobilePaymentData = initMobilePaymentData(sessionData);
|
||||
@ -149,7 +153,7 @@ public class CtxToEntryModelConverter implements Converter<PaymentContext, Entry
|
||||
}
|
||||
|
||||
private boolean isMobilePay(SessionData sessionData) {
|
||||
return sessionData.isSetAuthData() && sessionData.getAuthData().isSetAuth3ds();
|
||||
return sessionData != null && sessionData.isSetAuthData() && sessionData.getAuthData().isSetAuth3ds();
|
||||
}
|
||||
|
||||
private RefundData initRefundData(PaymentInfo paymentInfo) {
|
||||
|
@ -0,0 +1,17 @@
|
||||
package dev.vality.adapter.flow.lib.flow.simple;
|
||||
|
||||
import dev.vality.adapter.flow.lib.flow.RecurrentResultIntentResolver;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
|
||||
import dev.vality.damsel.proxy_provider.RecurrentTokenIntent;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class UnsupportedGenerateTokenResultIntentResolver implements RecurrentResultIntentResolver {
|
||||
|
||||
@Override
|
||||
public RecurrentTokenIntent initIntentByStep(ExitStateModel exitStateModel) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package dev.vality.adapter.flow.lib.flow.simple;
|
||||
|
||||
import dev.vality.adapter.flow.lib.constant.Step;
|
||||
import dev.vality.adapter.flow.lib.flow.AbstractGenerateTokenStepResolver;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
|
||||
public class UnsupportedGenerateTokenStepResolverImpl extends
|
||||
AbstractGenerateTokenStepResolver<EntryStateModel, ExitStateModel> {
|
||||
|
||||
@Override
|
||||
public Step resolveCurrentStep(EntryStateModel stateModel) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Step resolveNextStep(ExitStateModel exitStateModel) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
@ -1,43 +1,11 @@
|
||||
package dev.vality.adapter.flow.lib.handler;
|
||||
|
||||
import dev.vality.adapter.flow.lib.exception.UnknownHandlerForStepException;
|
||||
import dev.vality.adapter.flow.lib.flow.StepResolver;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.thrift.TException;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
import java.util.List;
|
||||
public interface ServerFlowHandler<T, R> {
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ServerFlowHandler<T, R> {
|
||||
|
||||
private final List<CommonHandler<ExitStateModel, EntryStateModel>> handlers;
|
||||
private final StepResolver<EntryStateModel, ExitStateModel> stepResolver;
|
||||
private final Converter<T, EntryStateModel> entryConverter;
|
||||
private final Converter<ExitStateModel, R> exitConverter;
|
||||
|
||||
public R handle(T context) throws TException {
|
||||
var entryStateModel = prepareEntryState(entryConverter, context);
|
||||
log.info("EntryStateModel: {}", entryStateModel);
|
||||
var exitStateModel = handlers.stream()
|
||||
.filter(handler -> handler.isHandle(entryStateModel))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new UnknownHandlerForStepException("Can't find handler to data: " + entryStateModel))
|
||||
.handle(entryStateModel);
|
||||
log.info("ExitStateModel: {}", exitStateModel);
|
||||
exitStateModel.setEntryStateModel(entryStateModel);
|
||||
exitStateModel.setNextStep(stepResolver.resolveNextStep(exitStateModel));
|
||||
log.info("Step changing: {} -> {}", entryStateModel.getCurrentStep(), exitStateModel.getNextStep());
|
||||
return exitConverter.convert(exitStateModel);
|
||||
default R handle(T context) throws TException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
private EntryStateModel prepareEntryState(Converter<T, EntryStateModel> entryConverter, T context) {
|
||||
EntryStateModel entryStateModel = entryConverter.convert(context);
|
||||
entryStateModel.setCurrentStep(stepResolver.resolveCurrentStep(entryStateModel));
|
||||
return entryStateModel;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
package dev.vality.adapter.flow.lib.handler;
|
||||
|
||||
import dev.vality.adapter.flow.lib.exception.UnknownHandlerForStepException;
|
||||
import dev.vality.adapter.flow.lib.flow.StepResolver;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.thrift.TException;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class ServerFlowHandlerImpl<T, R> implements ServerFlowHandler<T, R> {
|
||||
|
||||
private final List<CommonHandler<ExitStateModel, EntryStateModel>> handlers;
|
||||
private final StepResolver<EntryStateModel, ExitStateModel> stepResolver;
|
||||
private final Converter<T, EntryStateModel> entryConverter;
|
||||
private final Converter<ExitStateModel, R> exitConverter;
|
||||
|
||||
@Override
|
||||
public R handle(T context) throws TException {
|
||||
var entryStateModel = prepareEntryState(entryConverter, context);
|
||||
log.info("EntryStateModel: {}", entryStateModel);
|
||||
var exitStateModel = handlers.stream()
|
||||
.filter(handler -> handler.isHandle(entryStateModel))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new UnknownHandlerForStepException("Can't find handler to data: " + entryStateModel))
|
||||
.handle(entryStateModel);
|
||||
log.info("ExitStateModel: {}", exitStateModel);
|
||||
exitStateModel.setEntryStateModel(entryStateModel);
|
||||
exitStateModel.setNextStep(stepResolver.resolveNextStep(exitStateModel));
|
||||
log.info("Step changing: {} -> {}", entryStateModel.getCurrentStep(), exitStateModel.getNextStep());
|
||||
return exitConverter.convert(exitStateModel);
|
||||
}
|
||||
|
||||
private EntryStateModel prepareEntryState(Converter<T, EntryStateModel> entryConverter, T context) {
|
||||
EntryStateModel entryStateModel = entryConverter.convert(context);
|
||||
entryStateModel.setCurrentStep(stepResolver.resolveCurrentStep(entryStateModel));
|
||||
return entryStateModel;
|
||||
}
|
||||
}
|
@ -38,6 +38,10 @@ public class BaseResponseModel {
|
||||
* Data for choose 3ds flow and parameters for redirects.
|
||||
*/
|
||||
private ThreeDsData threeDsData;
|
||||
/**
|
||||
* Data for display qr code.
|
||||
*/
|
||||
private QrDisplayData qrDisplayData;
|
||||
/**
|
||||
* Data for support about transactions.
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@ public class ExitStateModel {
|
||||
private Map<String, String> trxExtra;
|
||||
private PollingInfo pollingInfo;
|
||||
private ThreeDsData threeDsData;
|
||||
private QrDisplayData qrDisplayData;
|
||||
private AdditionalTrxInfo additionalTrxInfo;
|
||||
|
||||
private String recToken;
|
||||
|
@ -0,0 +1,24 @@
|
||||
package dev.vality.adapter.flow.lib.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class QrDisplayData {
|
||||
|
||||
/**
|
||||
* Url for get qr code.
|
||||
*/
|
||||
private String qrUrl;
|
||||
|
||||
/**
|
||||
* Id for generate tag
|
||||
*/
|
||||
private String tagId;
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package dev.vality.adapter.flow.lib.processor;
|
||||
|
||||
import dev.vality.adapter.flow.lib.constant.Status;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
import dev.vality.adapter.flow.lib.utils.ErrorUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class QrDisplayProcessor implements Processor<ExitStateModel, BaseResponseModel, EntryStateModel> {
|
||||
|
||||
private final Processor<ExitStateModel, BaseResponseModel, EntryStateModel> nextProcessor;
|
||||
|
||||
@Override
|
||||
public ExitStateModel process(BaseResponseModel response, EntryStateModel entryStateModel) {
|
||||
if (response.getStatus() == Status.NEED_REDIRECT
|
||||
&& !ErrorUtils.isError(response)
|
||||
&& response.getQrDisplayData() != null
|
||||
&& response.getQrDisplayData().getQrUrl() != null) {
|
||||
log.debug("Start qr display process response: {} entryStateModel: {}", response, entryStateModel);
|
||||
ExitStateModel exitStateModel = new ExitStateModel();
|
||||
exitStateModel.setQrDisplayData(response.getQrDisplayData());
|
||||
exitStateModel.setLastOperationStatus(response.getStatus());
|
||||
exitStateModel.setProviderTrxId(response.getProviderTrxId());
|
||||
exitStateModel.setTrxExtra(response.getSaveData());
|
||||
exitStateModel.setAdditionalTrxInfo(response.getAdditionalTrxInfo());
|
||||
exitStateModel.setCustomContext(response.getCustomContext());
|
||||
log.debug("Finish qr display process response: {} entryStateModel: {}", response, entryStateModel);
|
||||
return exitStateModel;
|
||||
}
|
||||
|
||||
if (nextProcessor != null) {
|
||||
return nextProcessor.process(response, entryStateModel);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Processor didn't match for response " + response);
|
||||
}
|
||||
}
|
@ -18,7 +18,12 @@ public class TagManagementService {
|
||||
Optional<String> first = adapterProperties.getTagGeneratorFieldNames().stream()
|
||||
.filter(s -> StringUtils.hasText(parameters.get(s)))
|
||||
.findFirst();
|
||||
return adapterProperties.getTagPrefix() + parameters.get(first.get());
|
||||
String tagId = parameters.get(first.get());
|
||||
return initTag(tagId);
|
||||
}
|
||||
|
||||
public String initTag(String tagId) {
|
||||
return adapterProperties.getTagPrefix() + tagId;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,131 @@
|
||||
package dev.vality.adapter.flow.lib.service.factory;
|
||||
|
||||
import dev.vality.adapter.common.mapper.ErrorMapping;
|
||||
import dev.vality.adapter.flow.lib.constant.HttpMethod;
|
||||
import dev.vality.adapter.flow.lib.model.*;
|
||||
import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
|
||||
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
|
||||
import dev.vality.adapter.flow.lib.service.PollingInfoService;
|
||||
import dev.vality.adapter.flow.lib.service.TagManagementService;
|
||||
import dev.vality.adapter.flow.lib.utils.TimeoutUtils;
|
||||
import dev.vality.adapter.flow.lib.utils.TimerProperties;
|
||||
import dev.vality.damsel.base.Timer;
|
||||
import dev.vality.damsel.proxy_provider.*;
|
||||
import dev.vality.damsel.timeout_behaviour.TimeoutBehaviour;
|
||||
import dev.vality.damsel.user_interaction.QrCode;
|
||||
import dev.vality.damsel.user_interaction.QrCodeDisplayRequest;
|
||||
import dev.vality.damsel.user_interaction.UserInteraction;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.vality.adapter.common.damsel.OptionsExtractors.extractRedirectTimeout;
|
||||
import static dev.vality.adapter.common.damsel.ProxyProviderPackageCreators.*;
|
||||
import static dev.vality.adapter.flow.lib.utils.ThreeDsDataInitializer.TAG;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class IntentResultQrPaymentFactory implements IntentResultFactory {
|
||||
|
||||
private final TimerProperties timerProperties;
|
||||
private final TagManagementService tagManagementService;
|
||||
private final ParametersSerializer parametersSerializer;
|
||||
private final PollingInfoService pollingInfoService;
|
||||
private final ErrorMapping errorMapping;
|
||||
private final ExponentialBackOffPollingService exponentialBackOffPollingService;
|
||||
|
||||
@Override
|
||||
public Intent createFinishIntentSuccessWithCheckToken(ExitStateModel exitStateModel) {
|
||||
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
|
||||
if (entryStateModel.getBaseRequestModel().getRecurrentPaymentData() != null
|
||||
&& entryStateModel.getBaseRequestModel().getRecurrentPaymentData().isMakeRecurrent()) {
|
||||
return createFinishIntentSuccessWithToken(exitStateModel.getRecToken());
|
||||
}
|
||||
return createFinishIntentSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createSuspendIntentWithFailedAfterTimeout(ExitStateModel exitStateModel) {
|
||||
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
|
||||
QrDisplayData qrDisplayData = exitStateModel.getQrDisplayData();
|
||||
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
|
||||
int timerRedirectTimeoutMin = extractRedirectTimeout(
|
||||
adapterConfigurations,
|
||||
timerProperties.getRedirectTimeoutMin());
|
||||
return Intent.suspend(
|
||||
new SuspendIntent(
|
||||
tagManagementService.initTag(qrDisplayData.getTagId()),
|
||||
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin))
|
||||
).setUserInteraction(
|
||||
UserInteraction.qr_code_display_request(new QrCodeDisplayRequest()
|
||||
.setQrCode(new QrCode()
|
||||
.setPayload(qrDisplayData.getQrUrl().getBytes())))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createSuspendIntentWithCallbackAfterTimeout(ExitStateModel exitStateModel) {
|
||||
QrDisplayData qrDisplayData = exitStateModel.getQrDisplayData();
|
||||
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
|
||||
|
||||
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
|
||||
if (pollingInfoService.isDeadline(pollingInfo)) {
|
||||
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
|
||||
}
|
||||
exitStateModel.setPollingInfo(pollingInfo);
|
||||
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
|
||||
int timerRedirectTimeoutMin = extractRedirectTimeout(
|
||||
adapterConfigurations,
|
||||
timerProperties.getRedirectTimeoutMin());
|
||||
|
||||
|
||||
String tag = tagManagementService.initTag(qrDisplayData.getTagId());
|
||||
return Intent.suspend(
|
||||
new SuspendIntent(
|
||||
tag,
|
||||
Timer.timeout(TimeoutUtils.toSeconds(timerRedirectTimeoutMin)))
|
||||
.setTimeoutBehaviour(TimeoutBehaviour.callback(
|
||||
ByteBuffer.wrap(
|
||||
parametersSerializer.writeByte(Map.of(TAG, tag))))
|
||||
).setUserInteraction(
|
||||
UserInteraction.qr_code_display_request(new QrCodeDisplayRequest()
|
||||
.setQrCode(new QrCode()
|
||||
.setPayload(qrDisplayData.getQrUrl().getBytes()))))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createFinishIntentSuccess() {
|
||||
return Intent.finish(new FinishIntent(FinishStatus.success(new Success())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createSleepIntentWithExponentialPolling(ExitStateModel exitStateModel) {
|
||||
EntryStateModel entryStateModel = exitStateModel.getEntryStateModel();
|
||||
PollingInfo pollingInfo = pollingInfoService.initPollingInfo(entryStateModel);
|
||||
if (pollingInfoService.isDeadline(pollingInfo)) {
|
||||
return createFinishIntentFailed("Sleep timeout", "Max time pool limit reached");
|
||||
}
|
||||
exitStateModel.setPollingInfo(pollingInfo);
|
||||
|
||||
Map<String, String> adapterConfigurations = entryStateModel.getBaseRequestModel().getAdapterConfigurations();
|
||||
int nextTimeoutSec =
|
||||
exponentialBackOffPollingService.prepareNextPollingInterval(pollingInfo, adapterConfigurations);
|
||||
return Intent.sleep(new SleepIntent(Timer.timeout(nextTimeoutSec)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createFinishIntentFailed(ExitStateModel exitStateModel) {
|
||||
return Intent.finish(new FinishIntent(FinishStatus.failure(
|
||||
errorMapping.mapFailure(exitStateModel.getErrorCode(),
|
||||
exitStateModel.getErrorMessage()))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Intent createFinishIntentFailed(String errorCode, String errorMessage) {
|
||||
return Intent.finish(new FinishIntent(FinishStatus.failure(
|
||||
errorMapping.mapFailure(errorCode, errorMessage))));
|
||||
}
|
||||
|
||||
}
|
@ -22,6 +22,7 @@ import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
|
||||
import dev.vality.adapter.flow.lib.serde.TemporaryContextDeserializer;
|
||||
import dev.vality.adapter.flow.lib.serde.TemporaryContextSerializer;
|
||||
import dev.vality.adapter.flow.lib.service.*;
|
||||
import dev.vality.adapter.flow.lib.service.factory.IntentResultFactory;
|
||||
import dev.vality.adapter.flow.lib.service.factory.SimpleIntentResultFactory;
|
||||
import dev.vality.adapter.flow.lib.service.factory.SimpleRecurrentIntentResultFactory;
|
||||
import dev.vality.adapter.flow.lib.utils.AdapterProperties;
|
||||
@ -187,7 +188,7 @@ public class HandlerConfig {
|
||||
|
||||
@Bean
|
||||
public ExitModelToProxyResultConverter exitModelToProxyResultConverter(
|
||||
SimpleIntentResultFactory intentResultFactory,
|
||||
IntentResultFactory intentResultFactory,
|
||||
TemporaryContextSerializer temporaryContextSerializer,
|
||||
ResultIntentResolver resultIntentResolver,
|
||||
ExitStateModelToTemporaryContextConverter exitStateModelToTemporaryContextConverter) {
|
||||
|
@ -15,6 +15,7 @@ import dev.vality.adapter.flow.lib.flow.full.GenerateTokenResultIntentResolverIm
|
||||
import dev.vality.adapter.flow.lib.flow.full.ResultIntentResolverImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.CommonHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandlerImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.payment.*;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
@ -53,7 +54,7 @@ public class FullThreeDsFlowConfig {
|
||||
StepResolver<EntryStateModel, ExitStateModel> fullThreeDsAllVersionsStepResolverImpl,
|
||||
CtxToEntryModelConverter ctxToEntryModelConverter,
|
||||
ExitModelToProxyResultConverter exitModelToProxyResultConverter) {
|
||||
return new ServerFlowHandler<>(
|
||||
return new ServerFlowHandlerImpl<>(
|
||||
getHandlers(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
fullThreeDsAllVersionsStepResolverImpl,
|
||||
ctxToEntryModelConverter,
|
||||
@ -69,7 +70,7 @@ public class FullThreeDsFlowConfig {
|
||||
RecCtxToEntryModelConverter recCtxToEntryStateModelConverter,
|
||||
ExitModelToRecTokenProxyResultConverter exitModelToRecTokenProxyResultConverter
|
||||
) {
|
||||
return new ServerFlowHandler<>(
|
||||
return new ServerFlowHandlerImpl<>(
|
||||
getHandlers(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
generateTokenFullThreeDsAllVersionsStepResolverImpl,
|
||||
recCtxToEntryStateModelConverter,
|
||||
|
@ -0,0 +1,54 @@
|
||||
package dev.vality.adapter.flow.lib.flow.qr;
|
||||
|
||||
import dev.vality.adapter.flow.lib.flow.AbstractPaymentTest;
|
||||
import dev.vality.adapter.flow.lib.flow.qr.config.QrRedirectWithPollingDsFlowConfig;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.BeanUtils;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.MockUtil;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.damsel.proxy_provider.PaymentContext;
|
||||
import dev.vality.damsel.proxy_provider.PaymentProxyResult;
|
||||
import org.apache.thrift.TException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = QrRedirectWithPollingDsFlowConfig.class)
|
||||
@TestPropertySource(properties = {"server.rest.port=8083",
|
||||
"error-mapping.file=classpath:fixture/errors.json"})
|
||||
public class ErrorPaymentQrTest extends AbstractPaymentTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws TException {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
MockUtil.mockAllWithout3Ds(cdsStorageClient, benderClient);
|
||||
|
||||
BaseResponseModel baseResponseModel = BeanUtils.createBaseResponseModel();
|
||||
baseResponseModel.setErrorCode("rem_error_21");
|
||||
baseResponseModel.setErrorMessage("Remote service error!");
|
||||
|
||||
Mockito.when(client.auth(any())).thenReturn(baseResponseModel);
|
||||
Mockito.when(client.pay(any())).thenReturn(baseResponseModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testErrorPayment() throws TException {
|
||||
// pay
|
||||
PaymentContext paymentContext = MockUtil.buildPaymentContext(String.valueOf(new Date().getTime()),
|
||||
MockUtil.buildOptionsOneStage());
|
||||
|
||||
PaymentProxyResult paymentProxyResult = serverHandlerLogDecorator.processPayment(paymentContext);
|
||||
assertTrue(paymentProxyResult.getIntent().isSetFinish());
|
||||
assertTrue(paymentProxyResult.getIntent().getFinish().getStatus().isSetFailure());
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package dev.vality.adapter.flow.lib.flow.qr;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import dev.vality.adapter.flow.lib.constant.OptionFields;
|
||||
import dev.vality.adapter.flow.lib.constant.Stage;
|
||||
import dev.vality.adapter.flow.lib.constant.Status;
|
||||
import dev.vality.adapter.flow.lib.constant.Step;
|
||||
import dev.vality.adapter.flow.lib.flow.AbstractPaymentTest;
|
||||
import dev.vality.adapter.flow.lib.flow.qr.config.QrRedirectWithPollingDsFlowConfig;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.BeanUtils;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.MockUtil;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.damsel.proxy_provider.PaymentContext;
|
||||
import dev.vality.damsel.proxy_provider.PaymentProxyResult;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.thrift.TException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@Slf4j
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = QrRedirectWithPollingDsFlowConfig.class)
|
||||
@TestPropertySource(properties = {"error-mapping.file=classpath:fixture/errors.json",
|
||||
"adapter.callbackUrl=http://localhost:8080/test",
|
||||
"server.rest.endpoint=adapter",
|
||||
"server.rest.port=8083"})
|
||||
public class PaymentSuccessQrTest extends AbstractPaymentTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws TException {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
|
||||
MockUtil.mockIdGenerator(benderClient);
|
||||
|
||||
BaseResponseModel baseResponseModel = BeanUtils.createBaseResponseModel();
|
||||
baseResponseModel.setQrDisplayData(BeanUtils.createQrDisplayData());
|
||||
baseResponseModel.setStatus(Status.NEED_REDIRECT);
|
||||
|
||||
Mockito.when(client.auth(any())).thenReturn(baseResponseModel);
|
||||
Mockito.when(client.pay(any())).thenReturn(baseResponseModel);
|
||||
|
||||
BaseResponseModel successResponseModel = BeanUtils.createBaseResponseModel();
|
||||
Mockito.when(client.capture(any())).thenReturn(successResponseModel);
|
||||
Mockito.when(client.refund(any())).thenReturn(successResponseModel);
|
||||
Mockito.when(client.status(any())).thenReturn(successResponseModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneStage() throws TException, IOException {
|
||||
// auth
|
||||
Map<String, String> options = MockUtil.buildOptionsOneStage();
|
||||
testQr(options);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoStage() throws TException, IOException {
|
||||
// auth
|
||||
Map<String, String> options = MockUtil.buildOptionsTwoStage();
|
||||
testQr(options);
|
||||
}
|
||||
|
||||
private void testQr(Map<String, String> options) throws TException, JsonProcessingException {
|
||||
PaymentContext paymentContext = MockUtil.buildPaymentContextPaymentTerminal("invoice_id", options);
|
||||
|
||||
PaymentProxyResult paymentProxyResult = serverHandlerLogDecorator.processPayment(paymentContext);
|
||||
assertTrue(paymentProxyResult.getIntent().getSuspend().getUserInteraction().isSetQrCodeDisplayRequest());
|
||||
assertEquals(Step.CHECK_STATUS,
|
||||
temporaryContextDeserializer.read(paymentProxyResult.getNextState()).getNextStep());
|
||||
|
||||
//checkStatus
|
||||
paymentProxyResult = processWithDoNothingSuccessResult(paymentContext, paymentProxyResult);
|
||||
|
||||
//capture
|
||||
if (Stage.ONE.equals(options.get(OptionFields.STAGE.name()))) {
|
||||
paymentProxyResult = checkSuccessCapture(paymentContext, paymentProxyResult, new byte[] {});
|
||||
processWithDoNothingSuccessResult(paymentContext, paymentProxyResult);
|
||||
} else {
|
||||
paymentProxyResult = processCaptureWithCheckStatusResult(paymentContext, paymentProxyResult, new byte[] {});
|
||||
processWithCheckStatusResult(paymentContext, paymentProxyResult);
|
||||
}
|
||||
|
||||
//refund
|
||||
checkSuccessRefund(1100L, paymentContext, paymentProxyResult);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
package dev.vality.adapter.flow.lib.flow.qr.config;
|
||||
|
||||
import dev.vality.adapter.common.mapper.ErrorMapping;
|
||||
import dev.vality.adapter.flow.lib.client.RemoteClient;
|
||||
import dev.vality.adapter.flow.lib.converter.base.EntryModelToBaseRequestModelConverter;
|
||||
import dev.vality.adapter.flow.lib.converter.entry.CtxToEntryModelConverter;
|
||||
import dev.vality.adapter.flow.lib.converter.exit.ExitModelToProxyResultConverter;
|
||||
import dev.vality.adapter.flow.lib.flow.RecurrentResultIntentResolver;
|
||||
import dev.vality.adapter.flow.lib.flow.ResultIntentResolver;
|
||||
import dev.vality.adapter.flow.lib.flow.StepResolver;
|
||||
import dev.vality.adapter.flow.lib.flow.simple.SimpleRedirectWithPollingResultIntentResolver;
|
||||
import dev.vality.adapter.flow.lib.flow.simple.SimpleRedirectWithPollingStepResolverImpl;
|
||||
import dev.vality.adapter.flow.lib.flow.simple.UnsupportedGenerateTokenResultIntentResolver;
|
||||
import dev.vality.adapter.flow.lib.flow.simple.UnsupportedGenerateTokenStepResolverImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.CommonHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandlerImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.payment.*;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
import dev.vality.adapter.flow.lib.model.ExitStateModel;
|
||||
import dev.vality.adapter.flow.lib.processor.*;
|
||||
import dev.vality.adapter.flow.lib.serde.ParametersSerializer;
|
||||
import dev.vality.adapter.flow.lib.service.ExponentialBackOffPollingService;
|
||||
import dev.vality.adapter.flow.lib.service.PollingInfoService;
|
||||
import dev.vality.adapter.flow.lib.service.TagManagementService;
|
||||
import dev.vality.adapter.flow.lib.service.factory.IntentResultQrPaymentFactory;
|
||||
import dev.vality.adapter.flow.lib.utils.TimerProperties;
|
||||
import dev.vality.damsel.proxy_provider.PaymentContext;
|
||||
import dev.vality.damsel.proxy_provider.PaymentProxyResult;
|
||||
import dev.vality.damsel.proxy_provider.RecurrentTokenContext;
|
||||
import dev.vality.damsel.proxy_provider.RecurrentTokenProxyResult;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class QrRedirectWithPollingDsFlowConfig {
|
||||
|
||||
@Bean
|
||||
public StepResolver<EntryStateModel, ExitStateModel> stepResolverImpl() {
|
||||
return new SimpleRedirectWithPollingStepResolverImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public StepResolver<EntryStateModel, ExitStateModel> generateTokenStepResolverImpl() {
|
||||
return new UnsupportedGenerateTokenStepResolverImpl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerFlowHandler<PaymentContext, PaymentProxyResult> serverFlowHandler(
|
||||
RemoteClient client,
|
||||
EntryModelToBaseRequestModelConverter entryModelToBaseRequestModelConverter,
|
||||
Processor<ExitStateModel, BaseResponseModel, EntryStateModel> baseProcessor,
|
||||
StepResolver<EntryStateModel, ExitStateModel> stepResolverImpl,
|
||||
CtxToEntryModelConverter ctxToEntryModelConverter,
|
||||
ExitModelToProxyResultConverter exitModelToProxyResultConverter) {
|
||||
return new ServerFlowHandlerImpl<>(
|
||||
getHandlers(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
stepResolverImpl,
|
||||
ctxToEntryModelConverter,
|
||||
exitModelToProxyResultConverter);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public Processor<ExitStateModel, BaseResponseModel, EntryStateModel> baseProcessor() {
|
||||
ErrorProcessor errorProcessor = new ErrorProcessor();
|
||||
SuccessFinishProcessor baseProcessor = new SuccessFinishProcessor(errorProcessor);
|
||||
QrDisplayProcessor qrDisplayProcessor = new QrDisplayProcessor(baseProcessor);
|
||||
return new RetryProcessor(qrDisplayProcessor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RecurrentResultIntentResolver recurrentResultIntentResolver() {
|
||||
return new UnsupportedGenerateTokenResultIntentResolver();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ResultIntentResolver resultIntentResolver(IntentResultQrPaymentFactory intentResultFactory) {
|
||||
return new SimpleRedirectWithPollingResultIntentResolver(intentResultFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerFlowHandler<RecurrentTokenContext, RecurrentTokenProxyResult> generateTokenFlowHandler() {
|
||||
return new ServerFlowHandler<>() {
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IntentResultQrPaymentFactory intentResultFactory(
|
||||
TimerProperties timerProperties,
|
||||
TagManagementService tagManagementService,
|
||||
ParametersSerializer parametersSerializer,
|
||||
PollingInfoService pollingInfoService,
|
||||
ErrorMapping errorMapping,
|
||||
ExponentialBackOffPollingService exponentialBackOffPollingService) {
|
||||
return new IntentResultQrPaymentFactory(timerProperties, tagManagementService,
|
||||
parametersSerializer, pollingInfoService, errorMapping, exponentialBackOffPollingService);
|
||||
}
|
||||
|
||||
private List<CommonHandler<ExitStateModel, EntryStateModel>> getHandlers(
|
||||
RemoteClient client,
|
||||
EntryModelToBaseRequestModelConverter entryModelToBaseRequestModelConverter,
|
||||
Processor<ExitStateModel, BaseResponseModel, EntryStateModel> baseProcessor) {
|
||||
return List.of(new AuthHandler(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
new CancelHandler(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
new CaptureHandler(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
new StatusHandler(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
new DoNothingHandler(),
|
||||
new PaymentHandler(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
new RefundHandler(client, entryModelToBaseRequestModelConverter, baseProcessor));
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package dev.vality.adapter.flow.lib.flow.simple.redirect;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import dev.vality.adapter.flow.lib.constant.Status;
|
||||
import dev.vality.adapter.flow.lib.constant.Step;
|
||||
import dev.vality.adapter.flow.lib.flow.AbstractGenerateTokenTest;
|
||||
import dev.vality.adapter.flow.lib.flow.simple.redirect.config.SimpleRedirectWithPollingDsFlowConfig;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.BeanUtils;
|
||||
import dev.vality.adapter.flow.lib.flow.utils.MockUtil;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.damsel.proxy_provider.RecurrentTokenContext;
|
||||
import dev.vality.damsel.proxy_provider.RecurrentTokenProxyResult;
|
||||
import org.apache.thrift.TException;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.vality.adapter.flow.lib.flow.full.three.ds.ForwardRecurrentPaymentNon3dsTest.RECURRENT_TOKEN;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = SimpleRedirectWithPollingDsFlowConfig.class)
|
||||
@TestPropertySource(properties = {"server.rest.port=8083",
|
||||
"error-mapping.file=classpath:fixture/errors.json",
|
||||
"service.secret.enabled=true"})
|
||||
public class GenerateToken3ds1Test extends AbstractGenerateTokenTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws TException {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
MockUtil.mockAllWithout3Ds(cdsStorageClient, benderClient);
|
||||
|
||||
BaseResponseModel baseResponseModel = BeanUtils.createBaseResponseModel();
|
||||
baseResponseModel.setThreeDsData(BeanUtils.create3Ds1(baseResponseModel));
|
||||
baseResponseModel.setStatus(Status.NEED_REDIRECT);
|
||||
|
||||
BaseResponseModel baseResponseModelRec = BeanUtils.createBaseResponseModel();
|
||||
baseResponseModelRec.setRecurrentToken(RECURRENT_TOKEN);
|
||||
|
||||
Mockito.when(client.generateToken(any())).thenReturn(baseResponseModel);
|
||||
Mockito.when(client.status(any())).thenReturn(baseResponseModelRec);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaymentOneStage() throws TException, JsonProcessingException {
|
||||
// pay
|
||||
Map<String, String> options = MockUtil.buildOptionsOneStage();
|
||||
|
||||
RecurrentTokenContext paymentContext =
|
||||
MockUtil.buildRecurrentTokenContext(String.valueOf(new Date().getTime()),
|
||||
options);
|
||||
RecurrentTokenProxyResult paymentProxyResult = serverHandlerLogDecorator.generateToken(paymentContext);
|
||||
assertTrue(paymentProxyResult.getIntent().getSuspend().getUserInteraction().isSetRedirect());
|
||||
assertEquals(Step.CHECK_STATUS,
|
||||
temporaryContextDeserializer.read(paymentProxyResult.getNextState()).getNextStep());
|
||||
|
||||
//checkStatus
|
||||
paymentProxyResult = processWithDoNothingSuccessResult(paymentContext, paymentProxyResult);
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,7 @@ import dev.vality.adapter.flow.lib.flow.simple.SimpleRedirectWithPollingResultIn
|
||||
import dev.vality.adapter.flow.lib.flow.simple.SimpleRedirectWithPollingStepResolverImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.CommonHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandler;
|
||||
import dev.vality.adapter.flow.lib.handler.ServerFlowHandlerImpl;
|
||||
import dev.vality.adapter.flow.lib.handler.payment.*;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.adapter.flow.lib.model.EntryStateModel;
|
||||
@ -52,7 +53,7 @@ public class SimpleRedirectWithPollingDsFlowConfig {
|
||||
StepResolver<EntryStateModel, ExitStateModel> stepResolverImpl,
|
||||
CtxToEntryModelConverter ctxToEntryModelConverter,
|
||||
ExitModelToProxyResultConverter exitModelToProxyResultConverter) {
|
||||
return new ServerFlowHandler<>(
|
||||
return new ServerFlowHandlerImpl<>(
|
||||
getHandlers(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
stepResolverImpl,
|
||||
ctxToEntryModelConverter,
|
||||
@ -78,7 +79,7 @@ public class SimpleRedirectWithPollingDsFlowConfig {
|
||||
StepResolver<EntryStateModel, ExitStateModel> generateTokenStepResolverImpl,
|
||||
RecCtxToEntryModelConverter recCtxToEntryStateModelConverter,
|
||||
ExitModelToRecTokenProxyResultConverter exitModelToRecTokenProxyResultConverter) {
|
||||
return new ServerFlowHandler<>(
|
||||
return new ServerFlowHandlerImpl<>(
|
||||
getHandlers(client, entryModelToBaseRequestModelConverter, baseProcessor),
|
||||
generateTokenStepResolverImpl,
|
||||
recCtxToEntryStateModelConverter,
|
||||
|
@ -5,6 +5,7 @@ import dev.vality.adapter.common.utils.CommonConverter;
|
||||
import dev.vality.adapter.flow.lib.constant.Status;
|
||||
import dev.vality.adapter.flow.lib.constant.ThreeDsType;
|
||||
import dev.vality.adapter.flow.lib.model.BaseResponseModel;
|
||||
import dev.vality.adapter.flow.lib.model.QrDisplayData;
|
||||
import dev.vality.adapter.flow.lib.model.ThreeDsData;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@ -41,6 +42,13 @@ public class BeanUtils {
|
||||
.build();
|
||||
}
|
||||
|
||||
public static QrDisplayData createQrDisplayData() {
|
||||
return QrDisplayData.builder()
|
||||
.tagId("testTagId")
|
||||
.qrUrl("http://localhost/3ds")
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ThreeDsData create3Ds2FullCheck() {
|
||||
HashMap<String, String> parameters = new HashMap<>();
|
||||
parameters.put(THREE_DS_METHOD_DATA, "test_threeDsMethodData");
|
||||
|
@ -171,6 +171,38 @@ public class MockUtil {
|
||||
.setOptions(options);
|
||||
}
|
||||
|
||||
public static PaymentContext buildPaymentContextPaymentTerminal(String invoiceId, Map<String, String> options) {
|
||||
return new PaymentContext()
|
||||
.setSession(new Session()
|
||||
.setTarget(TargetInvoicePaymentStatus.processed(
|
||||
new InvoicePaymentProcessed())))
|
||||
.setPaymentInfo(new PaymentInfo()
|
||||
.setInvoice(new Invoice()
|
||||
.setId(invoiceId)
|
||||
.setDetails(new InvoiceDetails()
|
||||
.setDescription("details")))
|
||||
.setPayment(new InvoicePayment()
|
||||
.setId("payment_id")
|
||||
.setCreatedAt("2016-03-22T06:12:27Z")
|
||||
.setPaymentResource(PaymentResource.disposable_payment_resource(
|
||||
new DisposablePaymentResource()
|
||||
.setClientInfo(new ClientInfo()
|
||||
.setIpAddress("185.31.132.50"))
|
||||
.setPaymentTool(buildPaymentToolPaymentTerminal())))
|
||||
.setCost(new Cash()
|
||||
.setAmount(1200)
|
||||
.setCurrency(new Currency()
|
||||
.setSymbolicCode("RUB")
|
||||
.setNumericCode((short) 643)))
|
||||
.setContactInfo(new ContactInfo()
|
||||
.setEmail("kkkk@kkk.ru")
|
||||
.setPhoneNumber("89037772299"))
|
||||
)
|
||||
)
|
||||
|
||||
.setOptions(options);
|
||||
}
|
||||
|
||||
public static Map<String, String> buildOptionsOneStage() {
|
||||
return Map.of(OptionFields.STAGE.name(), Stage.ONE);
|
||||
}
|
||||
@ -190,6 +222,12 @@ public class MockUtil {
|
||||
);
|
||||
}
|
||||
|
||||
public static PaymentTool buildPaymentToolPaymentTerminal() {
|
||||
return PaymentTool.payment_terminal(
|
||||
new PaymentTerminal()
|
||||
);
|
||||
}
|
||||
|
||||
public static PaymentContext buildRecurrentPaymentContext(String invoiceId, String token) {
|
||||
PaymentContext paymentContext = MockUtil.buildPaymentContext(invoiceId,
|
||||
MockUtil.buildOptionsOneStage());
|
||||
|
Loading…
Reference in New Issue
Block a user