mirror of
https://github.com/jlengrand/adyen-java-spark-online-payments.git
synced 2026-03-10 08:01:24 +00:00
Finalized GET and POST redirect handling. Updated /payments request formating to support listed payment methods. Added config file initialization and updated README.md and .gitignore
This commit is contained in:
12
.gitignore
vendored
12
.gitignore
vendored
@@ -1,10 +1,14 @@
|
||||
.gradle
|
||||
.idea
|
||||
.gradle/
|
||||
.idea/
|
||||
|
||||
.DS_Store
|
||||
|
||||
gradle
|
||||
build
|
||||
gradle/
|
||||
build/
|
||||
bin/
|
||||
gen/
|
||||
|
||||
*.class
|
||||
|
||||
gradlew
|
||||
gradlew.bat
|
||||
20
README.md
20
README.md
@@ -8,7 +8,7 @@ This repository includes examples of PCI-compliant UI integrations for online pa
|
||||
|
||||
* [Drop-in](https://docs.adyen.com/checkout/drop-in-web)
|
||||
* [Component](https://docs.adyen.com/checkout/components-web)
|
||||
* ACH
|
||||
* ACH (not supported ATM b/c Java API Library doesn't support)
|
||||
* Alipay
|
||||
* Boleto
|
||||
* Card
|
||||
@@ -19,15 +19,24 @@ This repository includes examples of PCI-compliant UI integrations for online pa
|
||||
* Sofort
|
||||
|
||||
|
||||
## Requirements - TODO
|
||||
## Requirements
|
||||
|
||||
* Java 1.8
|
||||
* Gradle
|
||||
|
||||
## Dependencies
|
||||
The Gradle build will install the following files from maven central
|
||||
* Java Spark v2.8.0
|
||||
* Simple Logging Facade (slf4j-simple v1.7.25)
|
||||
* Jinjava template v2.7.1
|
||||
* org.apache.http URLEncodedUtils v4.5.11
|
||||
* Adyen Java API Library v5.0.0
|
||||
|
||||
|
||||
## Installation - TODO
|
||||
|
||||
1. Clone this repo
|
||||
2. ...
|
||||
2. Make sure you have Java 1.8 and Gradle installed on your machine
|
||||
|
||||
## Usage - TODO
|
||||
|
||||
@@ -37,10 +46,7 @@ This repository includes examples of PCI-compliant UI integrations for online pa
|
||||
checkout_apikey = SampleAPIKey
|
||||
origin_key = SampleOriginKey
|
||||
```
|
||||
2. Make sure your (venv) is activated by running `source ./venv/bin/activate` from your projects root.
|
||||
3. Run `./start.sh` to:
|
||||
* Initialize the required environment variables. This step is necessary every time you re-activate your (venv)
|
||||
* Run flask
|
||||
3. Run `gradle run`
|
||||
3. Visit [http://localhost:8080](http://localhost:8080) and select an integration type!
|
||||
|
||||
## Contributing
|
||||
|
||||
@@ -6,6 +6,11 @@ version "0.1"
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
description ="""
|
||||
Demo Adyen checkout integration with a Java Spark based backend
|
||||
Project name: ${project.name}
|
||||
"""
|
||||
|
||||
application {
|
||||
mainClassName = 'controller.Main'
|
||||
}
|
||||
@@ -19,5 +24,6 @@ dependencies {
|
||||
implementation "org.slf4j:slf4j-simple:1.7.25"
|
||||
implementation "com.sparkjava:spark-template-jinjava:2.7.1"
|
||||
implementation 'org.apache.httpcomponents:httpclient:4.5.11'
|
||||
implementation 'com.adyen:adyen-java-api-library:4.0.1'
|
||||
implementation 'com.adyen:adyen-java-api-library:5.0.0'
|
||||
implementation 'org.jetbrains:annotations:15.0'
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package controller;
|
||||
|
||||
import com.adyen.model.PaymentResult;
|
||||
import com.adyen.model.checkout.*;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package controller;
|
||||
|
||||
import com.adyen.model.checkout.PaymentDetails;
|
||||
import com.adyen.model.checkout.PaymentsDetailsRequest;
|
||||
import com.adyen.model.checkout.PaymentsRequest;
|
||||
import com.adyen.model.checkout.PaymentsResponse;
|
||||
@@ -8,12 +7,11 @@ import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.Closeables;
|
||||
import com.google.common.net.MediaType;
|
||||
import org.apache.http.NameValuePair;
|
||||
import spark.QueryParamsMap;
|
||||
import view.RenderUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
import model.PaymentMethods;
|
||||
@@ -27,6 +25,7 @@ import spark.Response;
|
||||
public class Main {
|
||||
|
||||
private static final File FAVICON_PATH = new File("src/main/resources/static/img/favicon.ico");
|
||||
private static final String configFile = "config.properties";
|
||||
|
||||
public static String merchantAccount = "";
|
||||
public static String apiKey = "";
|
||||
@@ -38,7 +37,7 @@ public class Main {
|
||||
public static void main(String[] args) {
|
||||
port(8080);
|
||||
staticFiles.location("/static");
|
||||
initalizeConstants();
|
||||
readConfigFile();
|
||||
|
||||
// Routes
|
||||
get("/", (req, res) -> {
|
||||
@@ -59,7 +58,7 @@ public class Main {
|
||||
String integrationType = req.params(":integration");
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
context.put("paymentMethods", PaymentMethods.getPaymentMethods());
|
||||
context.put("paymentMethods", PaymentMethods.getPaymentMethods(integrationType));
|
||||
context.put("originKey", originKey);
|
||||
context.put("integrationType", integrationType);
|
||||
|
||||
@@ -67,11 +66,13 @@ public class Main {
|
||||
});
|
||||
|
||||
post("/api/getPaymentMethods", (req, res) -> {
|
||||
String paymentMethods = PaymentMethods.getPaymentMethods();
|
||||
String paymentMethods = PaymentMethods.getPaymentMethods("");
|
||||
|
||||
return paymentMethods;
|
||||
});
|
||||
|
||||
post("/api/initiatePayment", (req, res) -> {
|
||||
System.out.println("Response received from client:\n" + req.body());
|
||||
PaymentsRequest request = FrontendParser.parsePayment(req.body());
|
||||
String response = Payments.makePayment(request);
|
||||
|
||||
@@ -86,24 +87,46 @@ public class Main {
|
||||
});
|
||||
|
||||
get("/api/handleShopperRedirect", (req, res) -> {
|
||||
System.out.println("GET result\n" + req.body());
|
||||
res.redirect("/error"); //TODO: Evaluate contents of res at this point to handle redirect
|
||||
return res;
|
||||
System.out.println("GET redirect handler");
|
||||
|
||||
QueryParamsMap queryMap = req.queryMap();
|
||||
String key = "";
|
||||
String value = "";
|
||||
|
||||
if (queryMap.hasKey("redirectResult")) {
|
||||
key = "redirectResult";
|
||||
value = queryMap.value("redirectResult");
|
||||
|
||||
} else if (queryMap.hasKey("payload")) {
|
||||
key = "payload";
|
||||
value = queryMap.value("payload");
|
||||
}
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
String valuesArray = "{\n" +
|
||||
"\"" + key + "\": \"" + value + "\"" +
|
||||
"}";
|
||||
context.put("valuesArray", valuesArray);
|
||||
|
||||
return RenderUtil.render(context, "templates/fetch-payment-data.html"); // Get paymentData from localStorage
|
||||
});
|
||||
|
||||
post("/api/handleShopperRedirect", (req, res) -> {
|
||||
System.out.println("POST result\n" + req.body() + "\n");
|
||||
System.out.println("POST redirect handler");
|
||||
|
||||
// Triggers when POST contains query params. Triggers on call back from issuer after 3DS2 challenge w/ MD & PaRes
|
||||
if (req.body().contains("&")) {
|
||||
if (!req.body().contains("paymentData")) {
|
||||
List<NameValuePair> params = FrontendParser.parseQueryParams(req.body());
|
||||
System.out.println(params.toString());
|
||||
String md = params.get(0).getValue();
|
||||
String paRes = params.get(1).getValue();
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
context.put("MD", md);
|
||||
context.put("PaRes", paRes);
|
||||
String valuesArray = "{\n" +
|
||||
"\"MD\": \"" + md + "\",\n" +
|
||||
"\"PaRes\": \"" + paRes + "\"\n" +
|
||||
"}";
|
||||
context.put("valuesArray", valuesArray);
|
||||
|
||||
return RenderUtil.render(context, "templates/fetch-payment-data.html"); // Get paymentData from localStorage
|
||||
|
||||
} else {
|
||||
@@ -115,8 +138,10 @@ public class Main {
|
||||
switch (result) {
|
||||
case AUTHORISED:
|
||||
res.redirect("/success");
|
||||
break;
|
||||
case RECEIVED: case PENDING:
|
||||
res.redirect("/pending");
|
||||
break;
|
||||
default:
|
||||
res.redirect("/failed");
|
||||
}
|
||||
@@ -149,15 +174,6 @@ public class Main {
|
||||
});
|
||||
}
|
||||
|
||||
private static void initalizeConstants() {
|
||||
merchantAccount = "TylerDouglas";
|
||||
apiKey = "AQEyhmfxL4jIYhVBw0m/n3Q5qf3VaY9UCJ1+XWZe9W27jmlZiiSaWGoa4mOFeQne5hiuhQsQwV1bDb7kfNy1WIxIIkxgBw==-hJYG90gqLYPclLs6We+q8CUtAsa+KgXr/iWftd+rrCM=-89EKHpWfW8ABmGF3";
|
||||
originKey = "pub.v2.8115499067697722.aHR0cDovL2xvY2FsaG9zdDo4MDgw.I4ixvXum4JGOjgI0Nd3YQ49P4AWvIncxMv41suCoW1Y";
|
||||
paymentMethodsUrl = "https://checkout-test.adyen.com/v52/paymentMethods";
|
||||
paymentsUrl = "https://checkout-test.adyen.com/v52/payments";
|
||||
paymentsDetailsUrl = "https://checkout-test.adyen.com/v52/payments/details";
|
||||
}
|
||||
|
||||
private static Object getFavicon(Response res) {
|
||||
try {
|
||||
InputStream in = null;
|
||||
@@ -180,4 +196,25 @@ public class Main {
|
||||
return ex.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private static void readConfigFile() {
|
||||
|
||||
Properties prop = new Properties();
|
||||
|
||||
try {
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(configFile));
|
||||
prop.load(in);
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
merchantAccount = prop.getProperty("merchantAccount");
|
||||
apiKey = prop.getProperty("apiKey");
|
||||
originKey = prop.getProperty("originKey");
|
||||
paymentMethodsUrl = prop.getProperty("paymentMethodsUrl");
|
||||
paymentsUrl = prop.getProperty("paymentsUrl");
|
||||
paymentsDetailsUrl = prop.getProperty("paymentsDetailsUrl");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package model;
|
||||
import com.adyen.Client;
|
||||
import com.adyen.enums.Environment;
|
||||
import com.adyen.model.Amount;
|
||||
import com.adyen.model.checkout.PaymentMethodDetails;
|
||||
import com.adyen.model.checkout.PaymentMethodsRequest;
|
||||
import com.adyen.model.checkout.PaymentMethodsResponse;
|
||||
import com.adyen.service.Checkout;
|
||||
@@ -16,15 +15,19 @@ import java.io.IOException;
|
||||
|
||||
public class PaymentMethods {
|
||||
|
||||
public static String getPaymentMethods() {
|
||||
public static String getPaymentMethods(String type) {
|
||||
Client client = new Client(Main.apiKey, Environment.TEST);
|
||||
Checkout checkout = new Checkout(client);
|
||||
|
||||
PaymentMethodsRequest paymentMethodsRequest = new PaymentMethodsRequest();
|
||||
paymentMethodsRequest.setMerchantAccount(Main.merchantAccount);
|
||||
paymentMethodsRequest.setCountryCode("NL");
|
||||
|
||||
Amount amount = new Amount();
|
||||
amount.setCurrency("EUR");
|
||||
if (type.equals("dotpay")) {
|
||||
amount.setCurrency("PLN");
|
||||
} else {
|
||||
amount.setCurrency("EUR");
|
||||
}
|
||||
amount.setValue(1000L);
|
||||
paymentMethodsRequest.setAmount(amount);
|
||||
paymentMethodsRequest.setChannel(PaymentMethodsRequest.ChannelEnum.WEB);
|
||||
|
||||
@@ -2,8 +2,8 @@ package model;
|
||||
|
||||
import com.adyen.Client;
|
||||
import com.adyen.enums.Environment;
|
||||
import com.adyen.model.Address;
|
||||
import com.adyen.model.Amount;
|
||||
import com.adyen.model.checkout.LineItem;
|
||||
import com.adyen.model.checkout.PaymentsRequest;
|
||||
import com.adyen.model.checkout.PaymentsResponse;
|
||||
import com.adyen.service.Checkout;
|
||||
@@ -21,16 +21,43 @@ public class Payments {
|
||||
Client client = new Client(Main.apiKey, Environment.TEST);
|
||||
Checkout checkout = new Checkout(client);
|
||||
|
||||
paymentsRequest.setMerchantAccount(Main.merchantAccount);
|
||||
paymentsRequest.setCountryCode("NL");
|
||||
Amount amount = new Amount();
|
||||
amount.setCurrency("EUR");
|
||||
amount.setValue(1000L);
|
||||
paymentsRequest.setAmount(amount);
|
||||
paymentsRequest.setReference("Test Reference");
|
||||
paymentsRequest.setReturnUrl("http://localhost:8080/api/handleShopperRedirect");
|
||||
String type = paymentsRequest.getPaymentMethod().getType();
|
||||
|
||||
setAmount(paymentsRequest, type);
|
||||
paymentsRequest.setChannel(PaymentsRequest.ChannelEnum.WEB);
|
||||
System.out.println("/paymentMethods response:\n" + paymentsRequest.toString());
|
||||
paymentsRequest.setMerchantAccount(Main.merchantAccount);
|
||||
paymentsRequest.setReturnUrl("http://localhost:8080/api/handleShopperRedirect");
|
||||
|
||||
paymentsRequest.setReference("Java Integration Test Reference");
|
||||
paymentsRequest.setShopperReference("Java Checkout Shopper");
|
||||
|
||||
paymentsRequest.setCountryCode("NL");
|
||||
|
||||
if (type.equals("alipay")) {
|
||||
paymentsRequest.setCountryCode("CN");
|
||||
|
||||
} else if (type.contains("klarna")) {
|
||||
paymentsRequest.setShopperEmail("myEmail@adyen.com");
|
||||
paymentsRequest.setShopperLocale("en_US");
|
||||
|
||||
addLineItems(paymentsRequest);
|
||||
|
||||
} else if (type.equals("directEbanking") || type.equals("giropay")) {
|
||||
paymentsRequest.countryCode("DE");
|
||||
|
||||
} else if (type.equals("dotpay")) {
|
||||
paymentsRequest.countryCode("PL");
|
||||
paymentsRequest.getAmount().setCurrency("PLN");
|
||||
|
||||
} else if (type.equals("scheme")) {
|
||||
paymentsRequest.setOrigin("http://localhost:8080");
|
||||
paymentsRequest.putAdditionalDataItem("allow3DS2", "true");
|
||||
|
||||
} else if (type.equals("ach")) {
|
||||
paymentsRequest.countryCode("US");
|
||||
}
|
||||
|
||||
System.out.println("/payments request:\n" + paymentsRequest.toString());
|
||||
|
||||
try {
|
||||
PaymentsResponse response = checkout.payments(paymentsRequest);
|
||||
@@ -45,4 +72,62 @@ public class Payments {
|
||||
return e.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void setAmount(PaymentsRequest paymentsRequest, String type) {
|
||||
Amount amount = new Amount();
|
||||
|
||||
String currency;
|
||||
|
||||
switch (type) {
|
||||
case "alipay":
|
||||
currency = "CNY";
|
||||
break;
|
||||
case "dotpay":
|
||||
currency = "PLN";
|
||||
break;
|
||||
case "boletobancario":
|
||||
currency = "BRL";
|
||||
break;
|
||||
case "ach":
|
||||
currency = "USD";
|
||||
break;
|
||||
default:
|
||||
currency = "EUR";
|
||||
}
|
||||
|
||||
amount.setCurrency(currency);
|
||||
amount.setValue(1000L);
|
||||
paymentsRequest.setAmount(amount);
|
||||
}
|
||||
|
||||
private static void addLineItems(PaymentsRequest paymentsRequest) {
|
||||
String item1 = "{\n" +
|
||||
" \"quantity\": \"1\",\n" +
|
||||
" \"amountExcludingTax\": \"450\",\n" +
|
||||
" \"taxPercentage\": \"1111\",\n" +
|
||||
" \"description\": \"Sunglasses\",\n" +
|
||||
" \"id\": \"Item #1\",\n" +
|
||||
" \"taxAmount\": \"50\",\n" +
|
||||
" \"amountIncludingTax\": \"500\",\n" +
|
||||
" \"taxCategory\": \"High\"\n" +
|
||||
" }";
|
||||
String item2 = "{\n" +
|
||||
" \"quantity\": \"1\",\n" +
|
||||
" \"amountExcludingTax\": \"450\",\n" +
|
||||
" \"taxPercentage\": \"1111\",\n" +
|
||||
" \"description\": \"Headphones\",\n" +
|
||||
" \"id\": \"Item #2\",\n" +
|
||||
" \"taxAmount\": \"50\",\n" +
|
||||
" \"amountIncludingTax\": \"500\",\n" +
|
||||
" \"taxCategory\": \"High\"\n" +
|
||||
" }";
|
||||
|
||||
Gson gson = new GsonBuilder().create();
|
||||
LineItem lineItem1 = gson.fromJson(item1, LineItem.class);
|
||||
LineItem lineItem2 = gson.fromJson(item2, LineItem.class);
|
||||
|
||||
paymentsRequest.addLineItemsItem(lineItem1);
|
||||
paymentsRequest.addLineItemsItem(lineItem2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,7 @@
|
||||
|
||||
const structurePaymentRequest = () => {
|
||||
const paymentData = localStorage.getItem('redirectPaymentData');
|
||||
let values_array = {
|
||||
"MD": "{{ MD }}",
|
||||
"PaRes": "{{ PaRes }}"
|
||||
};
|
||||
let values_array = {{ valuesArray }};
|
||||
const values = {
|
||||
paymentData: paymentData,
|
||||
details: values_array
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li class="integration-list-item">
|
||||
<a class="integration-list-item-link" href="cart/directEBanking">
|
||||
<a class="integration-list-item-link" href="cart/directEbanking">
|
||||
<div class="title-container">
|
||||
<p class="integration-list-item-title">Sofort</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user