├── .gitignore ├── .travis.yml ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── liqpay │ ├── LiqPay.java │ ├── LiqPayApi.java │ ├── LiqPayRequest.java │ └── LiqPayUtil.java └── test └── java └── com └── liqpay ├── LiqPayRequestTest.java ├── LiqPayTest.java └── LiqPayUtilTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | target 3 | .classpath 4 | .project 5 | .idea 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | liqpay.ua API SDK for Java 2 | =========================== 3 | 4 | [![Build Status](https://travis-ci.org/stokito/sdk-java.png?branch=master)](https://travis-ci.org/stokito/sdk-java) 5 | 6 | [liqpay.ua](https://www.liqpay.ua/) is payment system associated with [PrivatBank](https://privatbank.ua/). 7 | 8 | API Documentation [in Ukrainian](https://www.liqpay.ua/documentation) and [in English](https://www.liqpay.ua/en/documentation) 9 | 10 | **WARNING:** This SDK is not thread safe. We would be very appreciated for your contribution. 11 | 12 | Installation and usage 13 | ---------------------- 14 | 15 | This library is published at [GitHub](https://github.com/liqpay/sdk-java/) and can be added as Maven dependency. 16 | 17 | ### Use as Maven dependency 18 | 19 | Add to your `pom.xml` repository and dependency: 20 | 21 | ```xml 22 | 23 | 24 | repository 25 | https://github.com/liqpay/sdk-java/raw/repository 26 | 27 | true 28 | always 29 | 30 | 31 | 32 | 33 | 34 | com.liqpay 35 | liqpay-sdk 36 | 0.8-SNAPSHOT 37 | 38 | ``` 39 | 40 | Then you can use it as described in API documentation: 41 | 42 | ```java 43 | // Creation of the HTML-form 44 | Map params = new HashMap(); 45 | params.put("amount", "1.50"); 46 | params.put("currency", "USD"); 47 | params.put("description", "description text"); 48 | params.put("order_id", "order_id_1"); 49 | params.put("sandbox", "1"); // enable the testing environment and card will NOT charged. If not set will be used property isCnbSandbox() 50 | LiqPay liqpay = new LiqPay(PUBLIC_KEY, PRIVATE_KEY); 51 | String html = liqpay.cnb_form(params); 52 | System.out.println(html); 53 | ``` 54 | 55 | It is recommended to use some Inversion of Control (IoC) container, like [Spring IoC](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html) or [PicoContainer](http://picocontainer.codehaus.org/). 56 | 57 | #### Use proxy 58 | 59 | To use `LiqPay` with proxy you can initialize it like: 60 | 61 | ```java 62 | import java.net.InetSocketAddress; 63 | import java.net.Proxy; 64 | 65 | ... 66 | 67 | Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.host.com", 8080); 68 | LiqPay liqpay = new LiqPay(PUBLIC_KEY, PRIVATE_KEY, proxy, "proxyLogin", "some proxy password"); 69 | ``` 70 | 71 | 72 | ### Grails v2.x 73 | 74 | In `grails-app/conf/BuildConfig.groovy` you should add repository and dependency: 75 | 76 | ```groovy 77 | grails.project.dependency.resolution = { 78 | ... 79 | repositories { 80 | grailsPlugins() 81 | ... 82 | mavenRepo 'https://github.com/liqpay/sdk-java/raw/repository' 83 | } 84 | dependencies { 85 | ... 86 | compile 'com.liqpay:liqpay-sdk:0.8-SNAPSHOT' 87 | } 88 | ... 89 | } 90 | ``` 91 | 92 | Then you can add `LiqPay` bean in `grails-app/conf/spring/resources.groovy`: 93 | 94 | ```groovy 95 | import com.liqpay.LiqPay 96 | 97 | // Place your Spring DSL code here 98 | beans = { 99 | liqpay(LiqPay, '${com.liqpay.publicKey}', '${com.liqpay.privateKey}') { 100 | cnbSandbox = false // set true to enable the testing environment. Card is not charged 101 | } 102 | } 103 | ``` 104 | 105 | It will create bean with name `liqpay` of class `com.liqpay.LiqPay` and pass to it's constructor public and private keys that defined in `grails-app/conf/Config.groovy` like this: 106 | 107 | ```groovy 108 | com.liqpay.publicKey = 'i31219995456' 109 | com.liqpay.privateKey = '5czJZHmsjNJUiV0tqtBvPVaPJNZDyuoAIIYni68G' 110 | ``` 111 | 112 | Then you can use this `liqpay` bean with dependency injection in your services or controllers: 113 | 114 | ```groovy 115 | class UserController { 116 | LiqPayApi liqpay // this will inject liqpay bean defined in resources.groovy 117 | 118 | def balanceReplenishment() { 119 | Map params = [ 120 | "amount" : '30.5', 121 | "currency" : 'UAH', 122 | "description": 'Balance replenishmenton on example.com', 123 | "order_id" : "1", 124 | 'result_url' : g.createLink(action: 'paymentResult', absolute: true).toString()] 125 | String button = liqpay.cnb_form(params); 126 | [button: button] 127 | } 128 | } 129 | ``` 130 | 131 | And inside `grails-app/views/user/balanceReplenishment.gsp` you can output this button like this: 132 | 133 | ```gsp 134 |
135 | ${raw(button)} 136 |
137 | ``` 138 | 139 | 140 | Changelog 141 | --------- 142 | 143 | [All releases](https://github.com/stokito/sdk-java/releases) 144 | 145 | ### v0.1 First Mavenized version. 146 | 147 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.1) 148 | 149 | - Just reformatted code. 150 | - Created some basic tests. 151 | - API wasn't changed and this release can't broke compilation. 152 | 153 | ### v0.2 Improved tests 154 | 155 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.2) 156 | 157 | - Refactoring 158 | - More tests coverage 159 | - Parameter `params` of methods `cnb_form()` and `api()` now can by any `Map`, not only `HashMap`. 160 | - API wasn't changed and this release can't broke compilation. 161 | 162 | ### v0.3 Some methods deprecated 163 | 164 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.3) 165 | 166 | - Introduced API interface `LiqPayApi` 167 | - Deprecated fields that should be constant `host_checkout` and `liqpayApiUrl`. They was replaced with private constants. 168 | - Deprecated constructor `LiqPay(String publicKey, String privateKey, String liqpayApiUrl)` because `liqpayApiUrl` is constant and can't be rewritten. 169 | - Deprecated method `cnb_signature` because signature is already calculated inside `cnb_form(Map)`. 170 | - Deprecated shorthand method `setProxy(String host, Integer port)`, you should use full `setProxy(String host, Integer port, Proxy.Type)` instead. In next release v0.5 it will be deprecated too, and you should construct `Proxy` instance yourself. 171 | - API wasn't changed and this release can't broke compilation. 172 | 173 | ### v0.4 Last release that API compatible with old lib 174 | 175 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.4) 176 | 177 | - This release is recommended if you used original old lib since it shouldn't break compilation. 178 | - Params `version` and `public_key` are always set inside `cnb_form()` and `api()` methods. 179 | - Old version of `cnb_form()` accepted `public_key` parameter that can be differ from `publicKey`initialized in constructor. 180 | - Methods `cnb_form()` and `api()` doesn't add `public_key` and `version` to instance of `params` method. I.e. now you can pass unmodifable map and reuse it without side effects. 181 | - API wasn't changed and this release can't broke compilation. 182 | 183 | 184 | ### v0.5 Removed deprecated methods 185 | 186 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.5) 187 | 188 | - Removed deprecated method `cnb_signature` because signature is already calculated inside `cnb_form(Map)`. 189 | - Method `api()` now returns general `Map` instead of concrete `HashMap`. 190 | - Removed deprecated fields `liqpayApiUrl` and `host_checkout`. They replaced with constants `LiqPayApi.LIQPAY_API_URL` and `LiqPayApi.LIQPAY_API_CHECKOUT_URL`. 191 | - Introduced two new properties `proxyLogin` and `proxyPassword` that should be used instead of deprecated method `setProxyUser(login, password)`. 192 | - Introduced method `setProxy(Proxy)` that should be used instead of shorthand and deprecated `setProxy(host, port, Proxy.Type)`. 193 | - API **was changed** in this release and can broke compilation. 194 | 195 | ### v0.6 Enhanced usage 196 | 197 | [Source](https://github.com/stokito/grails-cookie/releases/tag/v0.6) 198 | 199 | - Created constructor `LiqPay(String publicKey, String privateKey, Proxy proxy, String proxyLogin, String proxyPassword)` that initialize API with proxy 200 | - Defined new property `isCnbSanbox()` that can globally set `sandbox` param in `cnb_form()` instead of specifying it always in `params` 201 | 202 | 203 | ### v0.7-SNAPSHOT 204 | - Changed url form liqpay.com to liqpay.ua 205 | 206 | ### v0.8-SNAPSHOT 207 | [Source]() 208 | - Changed cnb_form method. New form. -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | com.liqpay 4 | liqpay-sdk 5 | jar 6 | LiqPay payments API 7 | 0.8-SNAPSHOT 8 | https://www.liqpay.ua/documentation/en 9 | 10 | 11 | The Apache Software License, Version 2.0 12 | http://www.apache.org/licenses/LICENSE-2.0.txt 13 | 14 | 15 | 16 | scm:git:https://github.com/stokito/sdk-java.git 17 | scm:git:git@github.com:stokito/sdk-java.git 18 | https://github.com/stokito/sdk-java 19 | HEAD 20 | 21 | 22 | 23 | bintray 24 | https://api.bintray.com/maven/stokito/maven/liqpay-sdk 25 | 26 | 27 | 28 | 29 | UTF-8 30 | 31 | 32 | 33 | 34 | com.googlecode.json-simple 35 | json-simple 36 | 1.1.1 37 | 38 | 39 | junit 40 | junit 41 | 4.13.1 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-compiler-plugin 51 | 3.2 52 | 53 | true 54 | 1.8 55 | 1.8 56 | 57 | 58 | 59 | maven-release-plugin 60 | 2.5.1 61 | 62 | false 63 | release 64 | true 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | release 73 | 74 | 75 | 76 | maven-source-plugin 77 | 2.4 78 | 79 | 80 | attach-sources 81 | 82 | jar 83 | 84 | 85 | 86 | 87 | 88 | maven-javadoc-plugin 89 | 2.10.1 90 | 91 | 92 | attach-javadocs 93 | 94 | jar 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/main/java/com/liqpay/LiqPay.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import org.json.simple.JSONObject; 4 | import org.json.simple.parser.JSONParser; 5 | 6 | import java.net.Proxy; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.TreeMap; 10 | 11 | import static com.liqpay.LiqPayUtil.base64_encode; 12 | import static com.liqpay.LiqPayUtil.sha1; 13 | 14 | public class LiqPay implements LiqPayApi { 15 | private final JSONParser parser = new JSONParser(); 16 | private final String publicKey; 17 | private final String privateKey; 18 | private Proxy proxy; 19 | private String proxyLogin; 20 | private String proxyPassword; 21 | private boolean cnbSandbox; 22 | private boolean renderPayButton = true; 23 | // protected List supportedCurrencies = Arrays.asList("EUR", "UAH", "USD", "RUB", "GEL"); 24 | // protected List supportedParams = Arrays.asList("public_key", "amount", "currency", "description", "order_id", "result_url", "server_url", "type", "signature", "language", "sandbox"); 25 | 26 | public LiqPay(String publicKey, String privateKey) { 27 | this.publicKey = publicKey; 28 | this.privateKey = privateKey; 29 | checkRequired(); 30 | } 31 | 32 | public LiqPay(String publicKey, String privateKey, Proxy proxy, String proxyLogin, String proxyPassword) { 33 | this.publicKey = publicKey; 34 | this.privateKey = privateKey; 35 | this.proxy = proxy; 36 | this.proxyLogin = proxyLogin; 37 | this.proxyPassword = proxyPassword; 38 | checkRequired(); 39 | } 40 | 41 | private void checkRequired() { 42 | if (this.publicKey == null || this.publicKey.isEmpty()) { 43 | throw new IllegalArgumentException("publicKey is empty"); 44 | } 45 | if (this.privateKey == null || this.privateKey.isEmpty()) { 46 | throw new IllegalArgumentException("privateKey is empty"); 47 | } 48 | } 49 | 50 | public void setProxy(Proxy proxy) { 51 | this.proxy = proxy; 52 | } 53 | 54 | public Proxy getProxy() { 55 | return proxy; 56 | } 57 | 58 | public String getProxyLogin() { 59 | return proxyLogin; 60 | } 61 | 62 | public String getProxyPassword() { 63 | return proxyPassword; 64 | } 65 | 66 | public void setProxyLogin(String proxyLogin) { 67 | this.proxyLogin = proxyLogin; 68 | } 69 | 70 | public void setProxyPassword(String proxyPassword) { 71 | this.proxyPassword = proxyPassword; 72 | } 73 | 74 | public boolean isCnbSandbox() { 75 | return cnbSandbox; 76 | } 77 | 78 | public void setCnbSandbox(boolean cnbSandbox) { 79 | this.cnbSandbox = cnbSandbox; 80 | } 81 | 82 | public boolean isRenderPayButton() { 83 | return renderPayButton; 84 | } 85 | 86 | public void setRenderPayButton(boolean renderPayButton) { 87 | this.renderPayButton = renderPayButton; 88 | } 89 | 90 | @Override 91 | public Map api(String path, Map params) throws Exception { 92 | Map data = generateData(params); 93 | String resp = LiqPayRequest.post(LIQPAY_API_URL + path, data, this.getProxyLogin(), this.getProxyPassword(), this.getProxy()); 94 | JSONObject jsonObj = (JSONObject) parser.parse(resp); 95 | return LiqPayUtil.parseJson(jsonObj); 96 | } 97 | 98 | protected Map generateData(Map params) { 99 | HashMap apiData = new HashMap<>(); 100 | String data = base64_encode(JSONObject.toJSONString(withBasicApiParams(params))); 101 | apiData.put("data", data); 102 | apiData.put("signature", createSignature(data)); 103 | return apiData; 104 | } 105 | 106 | protected TreeMap withBasicApiParams(Map params) { 107 | TreeMap tm = new TreeMap<>(params); 108 | tm.put("public_key", publicKey); 109 | tm.put("version", API_VERSION); 110 | return tm; 111 | } 112 | 113 | protected TreeMap withSandboxParam(TreeMap params) { 114 | if (params.get("sandbox") == null && isCnbSandbox()) { 115 | TreeMap tm = new TreeMap<>(params); 116 | tm.put("sandbox", "1"); 117 | return tm; 118 | } 119 | return params; 120 | } 121 | 122 | protected String getBtnTxt(String lang) { 123 | switch (lang){ 124 | case "ru": 125 | return "Оплатить"; 126 | case "uk": 127 | return "Сплатити"; 128 | case "en": 129 | return "Pay"; 130 | default: 131 | return "Сплатити"; 132 | } 133 | } 134 | 135 | @Override 136 | public String cnb_form(Map params) { 137 | checkCnbParams(params); 138 | String data = base64_encode(JSONObject.toJSONString(withSandboxParam(withBasicApiParams(params)))); 139 | String signature = createSignature(data); 140 | String language = params.get("language") != null ? params.get("language") : DEFAULT_LANG; 141 | return renderHtmlForm(data, language, signature); 142 | } 143 | 144 | private String renderHtmlForm(String data, String language, String signature) { 145 | String form = ""; 146 | form += "
\n"; 147 | form += "\n"; 148 | form += "\n"; 149 | if (this.renderPayButton) { 150 | form += "\n" + 151 | ""; 152 | } 153 | form += "
\n"; 154 | return form; 155 | } 156 | 157 | protected void checkCnbParams(Map params) { 158 | if (params.get("amount") == null) 159 | throw new NullPointerException("amount can't be null"); 160 | if (params.get("currency") == null) 161 | throw new NullPointerException("currency can't be null"); 162 | if (params.get("description") == null) 163 | throw new NullPointerException("description can't be null"); 164 | } 165 | 166 | protected String str_to_sign(String str) { 167 | return base64_encode(sha1(str)); 168 | } 169 | 170 | protected String createSignature(String base64EncodedData) { 171 | return str_to_sign(privateKey + base64EncodedData + privateKey); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/main/java/com/liqpay/LiqPayApi.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public interface LiqPayApi { 7 | String API_VERSION = "3"; 8 | String LIQPAY_API_URL = "https://www.liqpay.ua/api/"; 9 | String LIQPAY_API_CHECKOUT_URL = "https://www.liqpay.ua/api/3/checkout"; 10 | String DEFAULT_LANG = "uk"; 11 | 12 | Map api(String path, Map params) throws Exception; 13 | 14 | /** 15 | * Liq and Buy 16 | * Payment acceptance on the site client to server 17 | * To accept payments on your site you will need: 18 | * Register on www.liqpay.ua 19 | * Create a store in your account using install master 20 | * Get a ready HTML-button or create a simple HTML form 21 | * HTML form should be sent by POST to URL https://www.liqpay.ua/api/3/checkout Two parameters data and signature, where: 22 | * data - function result base64_encode( $json_string ) 23 | * signature - function result base64_encode( sha1( $private_key . $data . $private_key ) ) 24 | */ 25 | String cnb_form(Map params); 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/liqpay/LiqPayRequest.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.DataOutputStream; 5 | import java.io.InputStreamReader; 6 | import java.net.HttpURLConnection; 7 | import java.net.Proxy; 8 | import java.net.URL; 9 | import java.net.URLEncoder; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.Map; 12 | 13 | import static com.liqpay.LiqPayUtil.base64_encode; 14 | 15 | public class LiqPayRequest { 16 | 17 | public static String post(String url, Map list, String proxyLogin, String proxyPassword, Proxy proxy) throws Exception { 18 | String urlParameters = ""; 19 | 20 | for (Map.Entry entry : list.entrySet()) 21 | urlParameters += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&"; 22 | 23 | URL obj = new URL(url); 24 | DataOutputStream wr; 25 | BufferedReader in; 26 | HttpURLConnection con; 27 | if (proxy == null) { 28 | con = (HttpURLConnection) obj.openConnection(); 29 | } else { 30 | con = (HttpURLConnection) obj.openConnection(proxy); 31 | if (proxyLogin != null) 32 | con.setRequestProperty("Proxy-Authorization", "Basic " + getProxyUser(proxyLogin, proxyPassword)); 33 | } 34 | con.setRequestMethod("POST"); 35 | con.setDoOutput(true); 36 | wr = new DataOutputStream(con.getOutputStream()); 37 | // Send post request 38 | wr.writeBytes(urlParameters); 39 | wr.flush(); 40 | wr.close(); 41 | in = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)); 42 | 43 | String inputLine; 44 | StringBuilder response = new StringBuilder(); 45 | 46 | while ((inputLine = in.readLine()) != null) { 47 | response.append(inputLine); 48 | } 49 | in.close(); 50 | return response.toString(); 51 | } 52 | 53 | public static String getProxyUser(String proxyLogin, String proxyPassword) { 54 | return base64_encode(proxyLogin + ":" + proxyPassword); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/liqpay/LiqPayUtil.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import java.security.MessageDigest; 4 | import java.text.ParseException; 5 | import java.util.ArrayList; 6 | import java.util.HashMap; 7 | import java.util.Set; 8 | 9 | import javax.xml.bind.DatatypeConverter; 10 | 11 | import org.json.simple.JSONArray; 12 | import org.json.simple.JSONObject; 13 | 14 | public class LiqPayUtil { 15 | public static byte[] sha1(String param) { 16 | try { 17 | MessageDigest SHA = MessageDigest.getInstance("SHA-1"); 18 | SHA.reset(); 19 | SHA.update(param.getBytes("UTF-8")); 20 | return SHA.digest(); 21 | } catch (Exception e) { 22 | throw new RuntimeException("Can't calc SHA-1 hash", e); 23 | } 24 | } 25 | 26 | public static String base64_encode(byte[] bytes) { 27 | return DatatypeConverter.printBase64Binary(bytes); 28 | } 29 | 30 | public static String base64_encode(String data) { 31 | return base64_encode(data.getBytes()); 32 | } 33 | 34 | public static ArrayList getArray(Object object2) throws ParseException { 35 | ArrayList list = new ArrayList(); 36 | JSONArray jsonArr = (JSONArray) object2; 37 | for (Object aJsonArr : jsonArr) { 38 | if (aJsonArr instanceof JSONObject) { 39 | list.add(parseJson((JSONObject) aJsonArr)); 40 | } else { 41 | list.add(aJsonArr); 42 | } 43 | } 44 | return list; 45 | } 46 | 47 | 48 | public static HashMap parseJson(JSONObject jsonObject) throws ParseException { 49 | HashMap data = new HashMap(); 50 | @SuppressWarnings("unchecked") 51 | Set set = jsonObject.keySet(); 52 | for (Object obj : set) { 53 | if (jsonObject.get(obj) instanceof JSONArray) { 54 | data.put(obj.toString(), getArray(jsonObject.get(obj))); 55 | } else { 56 | if (jsonObject.get(obj) instanceof JSONObject) { 57 | data.put(obj.toString(), parseJson((JSONObject) jsonObject.get(obj))); 58 | } else { 59 | data.put(obj.toString(), jsonObject.get(obj)); 60 | } 61 | } 62 | } 63 | return data; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/com/liqpay/LiqPayRequestTest.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | public class LiqPayRequestTest { 8 | 9 | @Test 10 | public void testGetProxyUser() { 11 | assertEquals("dXNlcjpwYXNz", LiqPayRequest.getProxyUser("user", "pass")); 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/java/com/liqpay/LiqPayTest.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import org.json.simple.JSONObject; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | 7 | import java.util.*; 8 | 9 | import static com.liqpay.LiqPayUtil.base64_encode; 10 | import static org.junit.Assert.*; 11 | 12 | public class LiqPayTest { 13 | 14 | static final String CNB_FORM_WITHOUT_SANDBOX = "
\n" + 15 | "\n" + 16 | "\n" + 17 | "\n" + 18 | "
\n"; 19 | 20 | static final String CNB_FORM_WITH_SANDBOX = "
\n" + 21 | "\n" + 22 | "\n" + 23 | "\n" + 24 | "
\n"; 25 | 26 | LiqPay lp; 27 | 28 | @Before 29 | public void setUp(){ 30 | lp = new LiqPay("publicKey", "privateKey"); 31 | } 32 | 33 | @Test 34 | public void testCnbFormWithoutSandboxParam() throws Exception { 35 | Map params = defaultTestParams("sandbox"); 36 | assertEquals(CNB_FORM_WITHOUT_SANDBOX, lp.cnb_form(params)); 37 | } 38 | 39 | @Test 40 | public void testCnbFormWithSandboxParam() throws Exception { 41 | Map params = defaultTestParams(null); 42 | assertEquals(CNB_FORM_WITH_SANDBOX, lp.cnb_form(params)); 43 | } 44 | 45 | @Test 46 | public void testCnbFormWillSetSandboxParamIfItEnabledGlobally() throws Exception { 47 | Map params = defaultTestParams("sandbox"); 48 | lp.setCnbSandbox(true); 49 | assertEquals(CNB_FORM_WITH_SANDBOX, lp.cnb_form(params)); 50 | } 51 | 52 | private Map defaultTestParams(String removedKey) { 53 | Map params = new TreeMap<>(); 54 | params.put("language", "en"); 55 | params.put("amount", "1.5"); 56 | params.put("currency", "USD"); 57 | params.put("description", "Description"); 58 | params.put("sandbox", "1"); 59 | if (removedKey!= null) { 60 | params.remove(removedKey); 61 | } 62 | return Collections.unmodifiableMap(params); 63 | } 64 | 65 | @Test 66 | public void testCnbParams() throws Exception { 67 | Map cnbParams = defaultTestParams(null); 68 | lp.checkCnbParams(cnbParams); 69 | assertEquals("en", cnbParams.get("language")); 70 | assertEquals("USD", cnbParams.get("currency")); 71 | assertEquals("1.5", cnbParams.get("amount")); 72 | assertEquals("Description", cnbParams.get("description")); 73 | } 74 | 75 | @Test(expected = NullPointerException.class) 76 | public void testCnbParamsTrowsNpeIfNotAmount() throws Exception { 77 | Map params = defaultTestParams("amount"); 78 | lp.checkCnbParams(params); 79 | } 80 | 81 | @Test(expected = NullPointerException.class) 82 | public void testCnbParamsTrowsNpeIfNotCurrency() throws Exception { 83 | Map params = defaultTestParams("currency"); 84 | lp.checkCnbParams(params); 85 | } 86 | 87 | @Test(expected = NullPointerException.class) 88 | public void testCnbParamsTrowsNpeIfNotDescription() throws Exception { 89 | Map params = defaultTestParams("description"); 90 | lp.checkCnbParams(params); 91 | } 92 | 93 | @Test 94 | public void testWithBasicApiParams() throws Exception { 95 | Map cnbParams = defaultTestParams(null); 96 | Map fullParams = lp.withBasicApiParams(cnbParams); 97 | assertEquals("publicKey", fullParams.get("public_key")); 98 | assertEquals("3", fullParams.get("version")); 99 | assertEquals("1.5", fullParams.get("amount")); 100 | } 101 | 102 | @Test 103 | public void testStrToSign() throws Exception { 104 | assertEquals("i0XkvRxqy4i+v2QH0WIF9WfmKj4=", lp.str_to_sign("some string")); 105 | } 106 | 107 | @Test 108 | public void testCreateSignature() throws Exception { 109 | JSONObject jsonObject = new JSONObject(); 110 | jsonObject.put("field", "value"); 111 | String base64EncodedData = base64_encode(jsonObject.toString()); 112 | assertEquals("d3dP/5qWQFlZgFR53eAwqJ+xIOQ=", lp.createSignature(base64EncodedData)); 113 | } 114 | 115 | @Test 116 | public void testGenerateData() throws Exception { 117 | Map invoiceParams = new TreeMap<>(); 118 | invoiceParams.put("email", "client-email@gmail.com"); 119 | invoiceParams.put("amount", "200"); 120 | invoiceParams.put("currency", "USD"); 121 | invoiceParams.put("order_id", "order_id_1"); 122 | invoiceParams.put("goods", "[{amount: 100, count: 2, unit: 'un.', name: 'phone'}]"); 123 | Map generated = lp.generateData(Collections.unmodifiableMap(invoiceParams)); 124 | assertEquals("DqcGjvo2aXgt0+zBZECdH4cbPWY=", generated.get("signature")); 125 | assertEquals("eyJhbW91bnQiOiIyMDAiLCJjdXJyZW5jeSI6IlVTRCIsImVtYWlsIjoiY2xpZW50LWVtYWlsQGdtYWlsLmNvbSIsImdvb2RzIjoiW3thbW91bnQ6IDEwMCwgY291bnQ6IDIsIHVuaXQ6ICd1bi4nLCBuYW1lOiAncGhvbmUnfV0iLCJvcmRlcl9pZCI6Im9yZGVyX2lkXzEiLCJwdWJsaWNfa2V5IjoicHVibGljS2V5IiwidmVyc2lvbiI6IjMifQ==", generated.get("data")); 126 | } 127 | } -------------------------------------------------------------------------------- /src/test/java/com/liqpay/LiqPayUtilTest.java: -------------------------------------------------------------------------------- 1 | package com.liqpay; 2 | 3 | import org.json.simple.JSONArray; 4 | import org.json.simple.JSONObject; 5 | import org.junit.Test; 6 | 7 | import java.text.ParseException; 8 | import java.util.Date; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import static com.liqpay.LiqPayUtil.*; 13 | import static org.junit.Assert.*; 14 | 15 | public class LiqPayUtilTest { 16 | 17 | @Test 18 | public void testSha1() { 19 | assertEquals("i0XkvRxqy4i+v2QH0WIF9WfmKj4=", base64_encode(sha1("some string"))); 20 | } 21 | 22 | @Test 23 | public void testBase64_encode() { 24 | assertEquals("c29tZSBzdHJpbmc=", base64_encode("some string".getBytes())); 25 | } 26 | 27 | @Test 28 | public void testBase64_encodeStr() { 29 | assertEquals("c29tZSBzdHJpbmc=", base64_encode("some string")); 30 | } 31 | 32 | @Test 33 | public void testGetArray() throws ParseException { 34 | // given: 35 | JSONArray jsonArray = new JSONArray(); 36 | jsonArray.add("string 1"); 37 | jsonArray.add("string 2"); 38 | JSONArray innerJsonArray = new JSONArray(); 39 | innerJsonArray.add("Inner string 1"); 40 | innerJsonArray.add(1); 41 | innerJsonArray.add(1L); 42 | innerJsonArray.add(1.0F); 43 | innerJsonArray.add(1.0D); 44 | jsonArray.add(innerJsonArray); 45 | Date someDate = new Date(); 46 | jsonArray.add(someDate); 47 | JSONObject innerJsonObject = new JSONObject(); 48 | innerJsonObject.put("stringField", "value"); 49 | innerJsonObject.put("intField", 42); 50 | innerJsonObject.put("longField", Long.MAX_VALUE); 51 | innerJsonObject.put("doubleField", 33.3D); 52 | jsonArray.add(innerJsonObject); 53 | // when: 54 | List parsedArray = getArray(jsonArray); 55 | // then: 56 | assertEquals("string 1", parsedArray.get(0)); 57 | assertEquals("string 2", parsedArray.get(1)); 58 | JSONArray parsedInnerJsonArray = (JSONArray) parsedArray.get(2); 59 | assertEquals("Inner string 1", parsedInnerJsonArray.get(0)); 60 | assertEquals(1, parsedInnerJsonArray.get(1)); 61 | assertEquals(1L, parsedInnerJsonArray.get(2)); 62 | assertEquals(1.0F, parsedInnerJsonArray.get(3)); 63 | assertEquals(1.0D, parsedInnerJsonArray.get(4)); 64 | assertEquals(someDate, (Date) parsedArray.get(3)); 65 | Map parsedInnerJsonObject = (Map) parsedArray.get(4); 66 | assertEquals("value", parsedInnerJsonObject.get("stringField")); 67 | assertEquals(42, parsedInnerJsonObject.get("intField")); 68 | assertEquals(Long.MAX_VALUE, parsedInnerJsonObject.get("longField")); 69 | assertEquals(33.3D, parsedInnerJsonObject.get("doubleField")); 70 | } 71 | 72 | @Test 73 | public void testParseJson() throws ParseException { 74 | // given: 75 | JSONObject jsonObject = new JSONObject(); 76 | jsonObject.put("stringField", "value"); 77 | jsonObject.put("intField", 42); 78 | jsonObject.put("longField", Long.MAX_VALUE); 79 | jsonObject.put("doubleField", 33.3D); 80 | JSONObject innerJsonObject = new JSONObject(); 81 | innerJsonObject.put("stringField", "value"); 82 | jsonObject.put("innerJsonObject", innerJsonObject); 83 | JSONArray jsonArray = new JSONArray(); 84 | jsonArray.add("string 1"); 85 | jsonArray.add("string 2"); 86 | jsonObject.put("array", jsonArray); 87 | // when: 88 | Map parsed = parseJson(jsonObject); 89 | // then: 90 | assertEquals("value", parsed.get("stringField")); 91 | assertEquals(42, parsed.get("intField")); 92 | assertEquals(Long.MAX_VALUE, parsed.get("longField")); 93 | assertEquals(33.3D, parsed.get("doubleField")); 94 | Map parsedInnerJsonObject = (Map) parsed.get("innerJsonObject"); 95 | assertEquals("value", parsedInnerJsonObject.get("stringField")); 96 | List parsedArray = (List) parsed.get("array"); 97 | assertEquals("string 1", parsedArray.get(0)); 98 | assertEquals("string 2", parsedArray.get(1)); 99 | } 100 | } --------------------------------------------------------------------------------