Skip to content

Commit

Permalink
#88911 Added refund() operation
Browse files Browse the repository at this point in the history
  • Loading branch information
Evgeniy Sinev committed Sep 29, 2020
1 parent f7d057a commit 2871ff3
Show file tree
Hide file tree
Showing 13 changed files with 312 additions and 50 deletions.
9 changes: 8 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

<android.version>4.1.1.4</android.version>

<reader.version>1.4-59</reader.version>
<reader.version>1.4-90</reader.version>
</properties>

<scm>
Expand Down Expand Up @@ -211,6 +211,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>

</dependencies>
</dependencyManagement>

Expand Down
5 changes: 5 additions & 0 deletions server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@
<artifactId>one-nio</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>

</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import com.payneteasy.pos.proxy.messages.PaymentRequest;
import com.payneteasy.pos.proxy.messages.PaymentResponse;
import com.payneteasy.pos.proxy.messages.RefundRequest;

public interface IPaymentService {

PaymentResponse pay(PaymentRequest aRequest);

PaymentResponse refund(RefundRequest aRequest);

}
22 changes: 22 additions & 0 deletions server/src/main/java/com/payneteasy/pos/proxy/WebServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.payneteasy.pos.proxy.messages.PaymentRequest;
import com.payneteasy.pos.proxy.messages.PaymentResponse;
import com.payneteasy.pos.proxy.messages.RefundRequest;
import one.nio.http.*;
import one.nio.server.AcceptorConfig;
import one.nio.util.ByteArrayBuilder;
Expand Down Expand Up @@ -68,6 +69,27 @@ public void pay(Request aRequest, HttpSession aSession) throws IOException {
});
}

@Path("/pos-proxy/refund")
public void refund(Request aRequest, HttpSession aSession) throws IOException {
PAYMENT_EXECUTOR.execute(() -> {
try {
String apiKey = aRequest.getHeader("X-API-Key");

if(!EXPECTED_API_KEY.equals(apiKey)) {
LOG.error("Expected X-API-Key is '{}' but was '{}'", EXPECTED_API_KEY, apiKey);
aSession.sendError(Response.FORBIDDEN, "Wrong X-API-Key");
return;
}
JsonMessages json = new JsonMessages(aRequest);
RefundRequest request = json.parse(RefundRequest.class);
PaymentResponse response = paymentService.refund(request);
aSession.sendResponse(json.response(response));
} catch (Exception e) {
sendError("Error while processing pay", aSession, e);
}
});
}

@Override
public void handleDefault(Request aRequest, HttpSession aSession) throws IOException {
if(aRequest.getURI().startsWith("/pos-proxy/swagger-ui")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.payneteasy.pos.proxy.impl;

import com.payneteasy.android.sdk.reader.inpas.config.InpasTerminalConfiguration;
import com.payneteasy.android.sdk.reader.inpas.network.InpasNetworkClient;
import com.payneteasy.inpas.sa.client.handlers.DefaultClientPacketOptions;
import com.payneteasy.pos.proxy.messages.PaymentResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class InpasNetworkManager {

private static final Logger LOG = LoggerFactory.getLogger(InpasNetworkManager.class);

private final String amount;
private final String currency;
private final String posAddress;

public InpasNetworkManager(String amount, String currency, String aPosAddress) {
this.amount = amount;
this.currency = currency;
posAddress = aPosAddress;
}

public interface IInpasOperationHandler {
PaymentResponse invokeOperation(InpasNetworkClient aClient) throws IOException;
}

public PaymentResponse makeOperation(IInpasOperationHandler aHandler) {
InpasNetworkClient client = new InpasNetworkClient(posAddress, new InpasTerminalConfiguration.Builder()
.packetOptions(new DefaultClientPacketOptions())
.throwExceptionIfCannotConnect(true)
.build()
);
try {
client.connect();
try {

return aHandler.invokeOperation(client);

} catch (Exception e) {
client.sendEot();
LOG.error("Cannot process a payment", e);
return error("-1");
} finally {
client.closeConnection();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted");
} catch (Exception e) {
LOG.error("Cannot connect", e);
return error("-2");
}

}

private PaymentResponse error(String aErrorCode) {
return PaymentResponse.builder()
.amount ( amount )
.currency ( currency )
.orderId ( null )
.responseCode ( aErrorCode )
.build();
}


}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package com.payneteasy.pos.proxy.impl;

import com.payneteasy.android.sdk.reader.inpas.config.InpasTerminalConfiguration;
import com.payneteasy.android.sdk.reader.inpas.config.InpasTerminalPacketOptions;
import com.payneteasy.android.sdk.reader.inpas.network.InpasNetworkClient;
import com.payneteasy.inpas.sa.messages.sale.Sa1PaymentResponse;
import com.payneteasy.inpas.sa.network.handlers.DefaultClientPacketOptions;
import com.payneteasy.inpas.sa.messages.sale.Sa29ReversalResponse;
import com.payneteasy.pos.proxy.IPaymentService;
import com.payneteasy.pos.proxy.messages.PaymentRequest;
import com.payneteasy.pos.proxy.messages.PaymentResponse;
import com.payneteasy.pos.proxy.messages.RefundRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.math.BigDecimal;

public class PaymentServiceImpl implements IPaymentService {
Expand All @@ -20,46 +17,44 @@ public class PaymentServiceImpl implements IPaymentService {

@Override
public PaymentResponse pay(PaymentRequest aRequest) {
InpasNetworkClient client = new InpasNetworkClient(aRequest.posAddress, new InpasTerminalConfiguration.Builder()
.packetOptions(new DefaultClientPacketOptions())
.throwExceptionIfCannotConnect(true)
.build()
);
try {
client.connect();
try {
Sa1PaymentResponse saResponse = client.makeSale(aRequest.currency, new BigDecimal(aRequest.amount));
InpasNetworkManager manager = new InpasNetworkManager(aRequest.getAmount(), aRequest.getCurrency(), aRequest.getPosAddress());

PaymentResponse response = new PaymentResponse();
response.amount = saResponse.get_00_amount().toString();
response.currency = "RUB";
response.orderId = getPaynetOrderId(saResponse);
response.responseCode = saResponse.get_15_responseCode();
return response;
return manager.makeOperation(aClient -> {
Sa1PaymentResponse saResponse = aClient.makeSale(aRequest.getCurrency(), new BigDecimal(aRequest.getAmount()));

} catch (Exception e) {
client.sendEot();
LOG.error("Cannot process a payment", e);
return error(aRequest, "-1");
} finally {
client.closeConnection();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted");
} catch (Exception e) {
LOG.error("Cannot connect", e);
return error(aRequest, "-2");
}
return PaymentResponse.builder()
.amount ( saResponse.get_00_amount().toString() )
.currency ( aRequest.getCurrency() )
.orderId ( getPaynetOrderId(saResponse) )
.responseCode ( saResponse.get_15_responseCode() )
.build();
});
}

private PaymentResponse error(PaymentRequest aRequest, String aErrorCode) {
PaymentResponse response = new PaymentResponse();
response.amount = aRequest.amount;
response.currency = "RUB";
response.orderId = null;
response.responseCode = aErrorCode;
return response;
@Override
public PaymentResponse refund(RefundRequest aRequest) {
InpasNetworkManager manager = new InpasNetworkManager(aRequest.getRefundAmount(), aRequest.getCurrency(), aRequest.getPosAddress());

return manager.makeOperation(aClient -> {
Sa29ReversalResponse saResponse = aClient.makeReversal(aRequest.getCurrency(), new BigDecimal(aRequest.getRefundAmount()), toRrn(aRequest.getOrderId()));

return PaymentResponse.builder()
.amount ( saResponse.get_00_amount().toString() )
.currency ( aRequest.getCurrency() )
.orderId ( aRequest.getOrderId() )
.responseCode ( saResponse.get_15_responseCode() )
.build();
});
}

public static String toRrn(long aOrderId) {
StringBuilder sb = new StringBuilder();
sb.append(aOrderId);
while(sb.length() < 11) {
sb.insert(0, "0");
}
sb.insert(0, "P");
return sb.toString();
}

private Long getPaynetOrderId(Sa1PaymentResponse saResponse) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package com.payneteasy.pos.proxy.messages;

import lombok.Data;
import lombok.NonNull;

@Data
public class PaymentRequest {

public String amount;
@NonNull
private final String amount;

public String currency;
@NonNull
private final String currency;

public String posAddress;
@NonNull
private final String posAddress;

public String posType;
@NonNull
private final String posType;

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package com.payneteasy.pos.proxy.messages;

import lombok.Builder;
import lombok.Data;
import lombok.NonNull;

@Data
@Builder
public class PaymentResponse {

public String amount;
public String currency;

public String responseCode;
@NonNull
private final String amount;

@NonNull
private final String currency;

@NonNull
private final String responseCode;

public Long orderId;
private final Long orderId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.payneteasy.pos.proxy.messages;

import lombok.Data;
import lombok.NonNull;

@Data
public class RefundRequest {

@NonNull
private final String refundAmount;

/**
* Paynet order id to refund
*/
private final long orderId;

@NonNull
private final String currency;

@NonNull
private final String posAddress;

@NonNull
private final String posType;

}
Loading

0 comments on commit 2871ff3

Please sign in to comment.