Skip to content

Commit

Permalink
Merge pull request #63 from xendit/feat/API-1334/qr-codes-api
Browse files Browse the repository at this point in the history
QR Code Implementation
  • Loading branch information
kevindavee authored Aug 13, 2020
2 parents ac5211f + da5431a commit 5781781
Show file tree
Hide file tree
Showing 6 changed files with 299 additions and 1 deletion.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ This library is the abstraction of Xendit API for access from applications writt
- [Cardless credit customer details](#cardless-credit-customer-details)
- [Cardless credit shipping address](#cardless-credit-shipping-address)
- [Create a cardless credit payment](#create-a-cardless-credit-payment)
- [QR Codes](#qr-codes)
- [Create QR Code](#create-qr-code)
- [Get QR Code](#get-qr-code)
- [Contributing](#contributing)
- [Lint](#lint)
- [Tests](#tests)
- [Precommit](#precommit)

Expand Down Expand Up @@ -896,11 +900,33 @@ CardlessCredit cardlessCredit = CardlessCredit.create(
);
```

### QR Code

#### Create QR Code

```java
QRCode qrCode = QRCode.create(
"external_id",
QRCode.QRCodeType.DYNAMIC,
"https://callback.site",
10000
);
```

#### Get QR Code

```java
QRCode qrCode = QRCode.getQRCode("external_id");
```

[Back to top](#table-of-contents)

## Contributing
You can go to the [contributing guidelines](https://github.com/xendit/xendit-java/blob/master/CONTRIBUTING.md) to learn on how to contribute this project.

### Lint
Run `./gradlew spotlessApply` to apply linter.

### Tests

Make sure the the code passes all tests.
Expand Down
2 changes: 1 addition & 1 deletion xendit-java-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
}

group 'com.xendit'
version '1.8.1'
version '1.9.0'

sourceCompatibility = 1.8

Expand Down
119 changes: 119 additions & 0 deletions xendit-java-lib/src/main/java/com/xendit/model/QRCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package com.xendit.model;

import com.google.gson.annotations.SerializedName;
import com.xendit.Xendit;
import com.xendit.exception.XenditException;
import com.xendit.network.RequestResource;
import java.util.HashMap;
import java.util.Map;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Builder
@Getter
@Setter
public class QRCode {
public enum QRCodeType {
DYNAMIC,
STATIC
}

public enum QRCodeStatus {
ACTIVE,
INACTIVE
}

@SerializedName("id")
private String id;

@SerializedName("external_id")
private String externalId;

@SerializedName("amount")
private Number amount;

@SerializedName("qr_string")
private String qrString;

@SerializedName("callback_url")
private String callbackUrl;

@SerializedName("type")
private String type;

@SerializedName("status")
private String status;

@SerializedName("created")
private String created;

@SerializedName("updated")
private String updated;

/**
* Create QR Code with given parameters
*
* @param externalId An ID of your choice. Often it is unique identifier in your system like
* customer ID or order ID
* @param type DYNAMIC or STATIC. DYNAMIC QR code contains the payment value upon scanning and can
* be paid multiple times. STATIC QR code requires end user to input the payment value and can
* be paid multiple times
* @param callbackUrl The URL to receive payment notification after payment has been made by end
* user
* @param amount The payment value embedded in the QR code, end user can only pay the specified
* amount after scanning the QR code. For STATIC QR code, amount parameter will be ignored.
* @return QRCode
* @throws XenditException XenditException
*/
public static QRCode createQRCode(
String externalId, QRCodeType type, String callbackUrl, Number amount)
throws XenditException {
Map<String, Object> params = new HashMap<>();
params.put("external_id", externalId);
params.put("type", type.toString());
params.put("callback_url", callbackUrl);
params.put("amount", amount);
String url = String.format("%s%s", Xendit.getUrl(), "/qr_codes");

return Xendit.requestClient.request(RequestResource.Method.POST, url, params, QRCode.class);
}

/**
* Create QR Code with parameters in a HashMap
*
* @param params listed here https://xendit.github.io/apireference/#create-qr-code
* @return QRCode
* @throws XenditException XenditException
*/
public static QRCode createQRCode(Map<String, Object> params) throws XenditException {
return createQRCode(new HashMap<>(), params);
}

/**
* Create QR Code with headers and parameters in a HashMap
*
* @param headers
* @param params listed here https://xendit.github.io/apireference/#create-qr-code
* @return QRCode
* @throws XenditException XenditException
*/
public static QRCode createQRCode(Map<String, String> headers, Map<String, Object> params)
throws XenditException {
String url = String.format("%s%s", Xendit.getUrl(), "/qr_codes");
return Xendit.requestClient.request(
RequestResource.Method.POST, url, headers, params, QRCode.class);
}

/**
* Get QR Code by external id
*
* @param externalId Merchant provided unique ID used to create QR code
* @return QRCode
* @throws XenditException XenditException
*/
public static QRCode getQRCode(String externalId) throws XenditException {
String url = String.format("%s%s%s", Xendit.getUrl(), "/qr_codes/", externalId);
return Xendit.requestClient.request(RequestResource.Method.GET, url, null, QRCode.class);
}
}
121 changes: 121 additions & 0 deletions xendit-java-lib/src/test/java/com/xendit/model/QRCodeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.xendit.model;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.xendit.Xendit;
import com.xendit.exception.XenditException;
import com.xendit.network.BaseRequest;
import com.xendit.network.RequestResource;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;

public class QRCodeTest {
private static String URL = String.format("%s%s", Xendit.getUrl(), "/qr_codes");
private static String TEST_ID = "test_id";
private static String TEST_EXTERNAL_ID = "test_external_id";
private static String TEST_QR_STRING = "this_is_qr_string";
private static String TEST_CALLBACK_URL = "https://callback.url";
private static String TEST_QR_TYPE = QRCode.QRCodeType.DYNAMIC.toString();
private static String TEST_QR_STATUS = QRCode.QRCodeStatus.ACTIVE.toString();
private static Map<String, Object> PARAMS = new HashMap<>();
private static Map<String, String> HEADERS = new HashMap<>();
private static QRCode VALID_PAYMENT =
QRCode.builder()
.id(TEST_ID)
.externalId(TEST_EXTERNAL_ID)
.qrString(TEST_QR_STRING)
.callbackUrl(TEST_CALLBACK_URL)
.status(TEST_QR_STATUS)
.amount(10000)
.build();

@Before
public void initMocks() {
Xendit.requestClient = mock(BaseRequest.class);
PARAMS.clear();
}

private void initCreateParams() {
PARAMS.put("external_id", TEST_EXTERNAL_ID);
PARAMS.put("type", TEST_QR_TYPE);
PARAMS.put("callback_url", TEST_CALLBACK_URL);
PARAMS.put("amount", 10000);
}

@Test
public void createQRCode_Success_IfMethodCalledCorrectly() throws XenditException {
initCreateParams();

when(Xendit.requestClient.request(RequestResource.Method.POST, URL, PARAMS, QRCode.class))
.thenReturn(VALID_PAYMENT);
QRCode qrCode =
QRCode.createQRCode(TEST_EXTERNAL_ID, QRCode.QRCodeType.DYNAMIC, TEST_CALLBACK_URL, 10000);

assertEquals(qrCode, VALID_PAYMENT);
}

@Test
public void createQRCode_Success_IfParamsIsValid() throws XenditException {
initCreateParams();

when(Xendit.requestClient.request(
RequestResource.Method.POST, URL, new HashMap<>(), PARAMS, QRCode.class))
.thenReturn(VALID_PAYMENT);
QRCode qrCode = QRCode.createQRCode(PARAMS);

assertEquals(qrCode, VALID_PAYMENT);
}

@Test(expected = XenditException.class)
public void createQRCode_ThrowsException_IfParamsIsInvalid() throws XenditException {
initCreateParams();
PARAMS.put("type", "NOT_DYNAMIC");

when(Xendit.requestClient.request(
RequestResource.Method.POST, URL, new HashMap<>(), PARAMS, QRCode.class))
.thenThrow(new XenditException("QR Code type is invalid"));

QRCode.createQRCode(PARAMS);
}

@Test
public void createQRCode_Success_WithHeaderProvided() throws XenditException {
initCreateParams();
HEADERS.put("for-user-id", "user-id");

when(Xendit.requestClient.request(
RequestResource.Method.POST, URL, HEADERS, PARAMS, QRCode.class))
.thenReturn(VALID_PAYMENT);

QRCode qrCode = QRCode.createQRCode(HEADERS, PARAMS);

assertEquals(qrCode, VALID_PAYMENT);
}

@Test
public void GetQRCode_Success_WithExternalId() throws XenditException {
String url = String.format("%s/%s", URL, TEST_EXTERNAL_ID);

when(Xendit.requestClient.request(RequestResource.Method.GET, url, null, QRCode.class))
.thenReturn(VALID_PAYMENT);

QRCode qrCode = QRCode.getQRCode(TEST_EXTERNAL_ID);

assertEquals(qrCode, VALID_PAYMENT);
}

@Test(expected = XenditException.class)
public void GetQRCode_ThrowsException_OnExternalIDNotFound() throws XenditException {
String NOT_VALID_EXTERNAL_ID = "not_valid_external_id";
String url = String.format("%s/%s", URL, NOT_VALID_EXTERNAL_ID);

when(Xendit.requestClient.request(RequestResource.Method.GET, url, null, QRCode.class))
.thenThrow(new XenditException("not found"));

QRCode.getQRCode(NOT_VALID_EXTERNAL_ID);
}
}
16 changes: 16 additions & 0 deletions xendit-java-library-example/src/main/java/ExampleCreateQRCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.xendit.Xendit;
import com.xendit.exception.XenditException;
import com.xendit.model.QRCode;

public class ExampleCreateQRCode {
public static void main(String[] args) {
Xendit.apiKey = "xnd_development_...";

try {
QRCode qrCode = QRCode.createQRCode("external_id", QRCode.QRCodeType.DYNAMIC, "https://webhook.site", 10000);
System.out.println(qrCode.getId());
} catch (XenditException e) {
e.printStackTrace();
}
}
}
16 changes: 16 additions & 0 deletions xendit-java-library-example/src/main/java/ExampleGetQRCode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import com.xendit.Xendit;
import com.xendit.exception.XenditException;
import com.xendit.model.QRCode;

public class ExampleGetQRCode {
public static void main(String[] args) {
Xendit.apiKey = "xnd_development_...";

try {
QRCode qrCode = QRCode.getQRCode("external_id_1");
System.out.println(qrCode.getId());
} catch (XenditException e) {
e.printStackTrace();
}
}
}

0 comments on commit 5781781

Please sign in to comment.