Skip to content

Commit

Permalink
Include refund functionality for terminal and ecom. Include QR paymen… (
Browse files Browse the repository at this point in the history
#11)

- Added refund functionality for terminal and ecom
- Added paymentMethodType for terminal payment

---------

Co-authored-by: Simon Billingsley <[email protected]>
  • Loading branch information
ioannis-kody and sishbi authored Dec 4, 2024
1 parent f3e571d commit ce860a2
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 44 deletions.
2 changes: 1 addition & 1 deletion samples/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {

description = "Kody Java gRPC Client Sample"

val kodyClientVersion by extra("0.0.3")
val kodyClientVersion by extra("0.0.5")

val protobufVersion by extra("4.27.3")
val grpcVersion by extra("1.66.0")
Expand Down
22 changes: 16 additions & 6 deletions samples/src/main/java/cli/PaymentInput.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
package cli;

import com.kodypay.grpc.pay.v1.PaymentMethodType;

public class PaymentInput {

private long amount;
private boolean showTips;
private PaymentMethodType paymentMethodType;

public long getAmount() {
return amount;
}

public void setAmount(long amount) {
this.amount = amount;
}

public boolean isShowTips() {
return showTips;
Expand All @@ -12,13 +24,11 @@ public void setShowTips(boolean showTips) {
this.showTips = showTips;
}

private boolean showTips;

public long getAmount() {
return amount;
public PaymentMethodType getPaymentMethodType() {
return paymentMethodType;
}

public void setAmount(long amount) {
this.amount = amount;
public void setPaymentMethodType(PaymentMethodType paymentMethodType) {
this.paymentMethodType = paymentMethodType;
}
}
93 changes: 78 additions & 15 deletions samples/src/main/java/common/PaymentClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@
import com.kodypay.grpc.ecom.v1.GetPaymentsResponse.Response.PaymentDetails;
import com.kodypay.grpc.ecom.v1.KodyEcomPaymentsServiceGrpc.KodyEcomPaymentsServiceStub;
import com.kodypay.grpc.ecom.v1.PaymentInitiationRequest.ExpirySettings;
import com.kodypay.grpc.pay.v1.CancelRequest;
import com.kodypay.grpc.pay.v1.CancelResponse;
import com.kodypay.grpc.pay.v1.KodyPayTerminalServiceGrpc;
import com.kodypay.grpc.pay.v1.KodyPayTerminalServiceGrpc.KodyPayTerminalServiceStub;
import com.kodypay.grpc.pay.v1.PayRequest;
import com.kodypay.grpc.pay.v1.PayResponse;
import com.kodypay.grpc.pay.v1.*;
import com.kodypay.grpc.pay.v1.PaymentDetailsRequest;
import com.kodypay.grpc.pay.v1.PaymentStatus;
import com.kodypay.grpc.pay.v1.Terminal;
import com.kodypay.grpc.pay.v1.TerminalsRequest;
import com.kodypay.grpc.pay.v1.TerminalsResponse;
import com.kodypay.grpc.pay.v1.RefundRequest;
import com.kodypay.grpc.pay.v1.RefundResponse;
import com.kodypay.grpc.pay.v1.KodyPayTerminalServiceGrpc.KodyPayTerminalServiceStub;
import com.kodypay.grpc.sdk.common.PageCursor;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
Expand Down Expand Up @@ -72,11 +66,7 @@ private Metadata getMetadata() {
return metadata;
}

public CompletableFuture<PayResponse> sendPayment(String terminalId, BigDecimal amount, java.util.function.Consumer<String> onPending) {
return sendPayment(terminalId, amount, false, onPending);
}

public CompletableFuture<PayResponse> sendPayment(String terminalId, BigDecimal amount, boolean showTips, java.util.function.Consumer<String> onPending) {
public CompletableFuture<PayResponse> sendPayment(String terminalId, BigDecimal amount, boolean showTips, PaymentMethodType paymentMethodType, java.util.function.Consumer<String> onPending) {
LOG.debug("sendPayment: storeId={}, amount={}, terminalId={} (address: {})", payStoreId, amount, terminalId, inetSocketAddress);

CompletableFuture<PayResponse> future = new CompletableFuture<>();
Expand All @@ -85,6 +75,7 @@ public CompletableFuture<PayResponse> sendPayment(String terminalId, BigDecimal
.setAmount(amount.toPlainString())
.setTerminalId(terminalId)
.setShowTips(showTips)
.setPaymentMethod(PaymentMethod.newBuilder().setPaymentMethodType(paymentMethodType).build())
.build(), new StreamObserver<>() {
PayResponse response;

Expand Down Expand Up @@ -154,6 +145,42 @@ public void onCompleted() {
return future;
}

public CompletableFuture<com.kodypay.grpc.ecom.v1.RefundResponse> requestOnlineRefund(String paymentId, long amount) {
LOG.debug("requestOnlineRefund: storeId={}, paymentId={}, amount={} (address: {})", payStoreId, paymentId, amount, inetSocketAddress);

CompletableFuture<com.kodypay.grpc.ecom.v1.RefundResponse> future = new CompletableFuture<>();
ecomServiceStub.refund(com.kodypay.grpc.ecom.v1.RefundRequest.newBuilder()
.setStoreId(payStoreId.toString())
.setPaymentId(paymentId)
.setAmount(String.valueOf(amount))
.build(), new StreamObserver<>() {
com.kodypay.grpc.ecom.v1.RefundResponse response;

@Override
public void onNext(com.kodypay.grpc.ecom.v1.RefundResponse res) {
response = res;
com.kodypay.grpc.ecom.v1.RefundResponse.RefundStatus refundStatus = response.getStatus();
LOG.debug("requestRefund: response={}", response);
if (refundStatus == com.kodypay.grpc.ecom.v1.RefundResponse.RefundStatus.FAILED) {
LOG.error("requestRefund: Failed to request refund, status={}, message={}", refundStatus, response);
}
}

@Override
public void onError(Throwable e) {
LOG.error("requestOnlineRefund: error requesting online refund, message={}, stack={}", e.getMessage(), e);
future.completeExceptionally(e);
}

@Override
public void onCompleted() {
LOG.debug("requestOnlineRefund: complete");
future.complete(response);
}
});
return future;
}

public CompletableFuture<PaymentStatus> cancelPayment(BigDecimal amount, String terminalId, String orderId) {
LOG.debug("cancelPayment: storeId={}, amount={}, terminalId={}, orderId={}", payStoreId, amount, terminalId, orderId);

Expand Down Expand Up @@ -191,6 +218,42 @@ public void onCompleted() {
return future;
}

public CompletableFuture<RefundResponse> requestRefund(BigDecimal amount, String orderId) {
LOG.debug("requestRefund: storeId={}, amount={}, orderId={}", payStoreId, amount, orderId);

CompletableFuture<RefundResponse> future = new CompletableFuture<>();
terminalServiceStub.refund(RefundRequest.newBuilder()
.setStoreId(payStoreId.toString())
.setAmount(amount.toPlainString())
.setOrderId(orderId)
.build(), new StreamObserver<>() {
RefundResponse response;

@Override
public void onNext(RefundResponse res) {
response = res;
RefundResponse.RefundStatus refundStatus = response.getStatus();
LOG.debug("requestRefund: response={}", response);
if (refundStatus == RefundResponse.RefundStatus.FAILED) {
LOG.error("requestRefund: Failed to request refund, status={}, message={}", refundStatus, response);
}
}

@Override
public void onError(Throwable e) {
LOG.error("requestRefund: Failed to request refund, message={}, stack={}", e.getMessage(), e);
future.completeExceptionally(e);
}

@Override
public void onCompleted() {
LOG.debug("requestRefund: complete");
future.complete(response);
}
});
return future;
}

public CompletableFuture<PayResponse> getDetails(String orderId) {
LOG.debug("getDetails: storeId={}, orderId={}", payStoreId, orderId);

Expand Down
21 changes: 16 additions & 5 deletions samples/src/main/java/ecom/EcomAsyncJavaClient.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package ecom;

import cli.EcomPaymentInput;
import cli.Command;
import cli.EcomPaymentInput;
import cli.PaymentCommand;
import com.kodypay.grpc.ecom.v1.*;
import com.kodypay.grpc.ecom.v1.GetPaymentsResponse.Response.PaymentDetails;
import com.kodypay.grpc.ecom.v1.PaymentInitiationResponse;
import com.kodypay.grpc.ecom.v1.RefundResponse;
import common.CurrencyEnum;
import common.PaymentClient;
import org.jline.reader.LineReader;
Expand Down Expand Up @@ -44,10 +45,10 @@ public CompletableFuture<PaymentInitiationResponse> sendPaymentAsync(long amount
String paymentReference = generatePaymentReference();
String orderId = generateOrderId();
String currency = CurrencyEnum.HKD.name();
return sendPaymentAsync(amount, paymentReference, currency, orderId);
return sendPaymentAsync(paymentReference, amount, currency, orderId);
}

private CompletableFuture<PaymentInitiationResponse> sendPaymentAsync(long amount, String currency, String paymentReference, String orderId) {
private CompletableFuture<PaymentInitiationResponse> sendPaymentAsync(String paymentReference, long amount, String currency, String orderId) {
LOG.info("Initiating payment for amount: {}", amount);

return client.sendOnlinePayment(paymentReference, amount, currency, orderId, "returnUrl")
Expand All @@ -57,6 +58,16 @@ private CompletableFuture<PaymentInitiationResponse> sendPaymentAsync(long amoun
});
}

CompletableFuture<RefundResponse> requestRefundAsync(String paymentId, long amount) {
LOG.info("Request refund for amount: {}", amount);

return client.requestOnlineRefund(paymentId, amount)
.thenApply(res -> {
LOG.info("Requested Online Refund - Response: {}", res);
return res;
});
}

public CompletableFuture<List<PaymentDetails>> getPayments() {
LOG.info("Get payments");

Expand Down Expand Up @@ -87,7 +98,7 @@ public SendPaymentCommand() {

@Override
public void execute() {
asyncClient.sendPaymentAsync(input.getAmount(), input.getCurrency(), input.getPaymentReference(), input.getOrderId());
asyncClient.sendPaymentAsync(input.getPaymentReference(), input.getAmount(), input.getCurrency(), input.getOrderId());
}

@Override
Expand Down
37 changes: 31 additions & 6 deletions samples/src/main/java/ecom/EcomBlockingJavaClient.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
package ecom;

import com.kodypay.grpc.ecom.v1.GetPaymentsResponse.Response.PaymentDetails;
import com.kodypay.grpc.ecom.v1.PaymentInitiationResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class EcomBlockingJavaClient {
private static final Logger LOG = LoggerFactory.getLogger(EcomBlockingJavaClient.class.getName());
private final EcomAsyncJavaClient asyncClient;

public EcomBlockingJavaClient() {
asyncClient = new EcomAsyncJavaClient();
}

public void sendOnlinePaymentBlocking(long amountStr) throws ExecutionException, InterruptedException, TimeoutException {
asyncClient.sendPaymentAsync(amountStr).get(1, TimeUnit.MINUTES);
public PaymentInitiationResponse sendOnlinePaymentBlocking(long amountStr) throws ExecutionException, InterruptedException, TimeoutException {
return asyncClient.sendPaymentAsync(amountStr).get(1, TimeUnit.MINUTES);
}

public void requestOnlineRefund(String paymentId, long amountStr) {
asyncClient.requestRefundAsync(paymentId, amountStr).thenAccept(it -> LOG.info("Requested refund response: {}", it));
}

public void getPaymentsBlocking() throws ExecutionException, InterruptedException, TimeoutException {
asyncClient.getPayments().get(1, TimeUnit.MINUTES);
public List<PaymentDetails> getPaymentsBlocking() throws ExecutionException, InterruptedException, TimeoutException {
return asyncClient.getPayments().get(1, TimeUnit.MINUTES);
}

public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {
EcomBlockingJavaClient ecomBlockingJavaClient = new EcomBlockingJavaClient();

long amountInPence = 100;
ecomBlockingJavaClient.getPaymentsBlocking();
ecomBlockingJavaClient.sendOnlinePaymentBlocking(amountInPence);
Optional<PaymentDetails> payment;
PaymentInitiationResponse paymentResponse = ecomBlockingJavaClient.sendOnlinePaymentBlocking(amountInPence);

// Wait for payment to be complete before refunding it
do {
LOG.info("Waiting for online payment to complete");
Thread.sleep(5000);
payment = ecomBlockingJavaClient
.getPaymentsBlocking()
.stream()
.filter(c -> c.getPaymentId().equals(paymentResponse.getResponse().getPaymentId()))
.findFirst();
} while (payment.isEmpty() || payment.stream().allMatch(e -> e.getStatus() == PaymentDetails.PaymentStatus.PENDING));

ecomBlockingJavaClient.requestOnlineRefund(paymentResponse.getResponse().getPaymentUrl(), amountInPence);
}
}
Loading

0 comments on commit ce860a2

Please sign in to comment.