Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ public class CollectionApiModel {
private List<DataApiModel> data = emptyList();

public Integer getPaginationOffset() {
return meta.getPaginationOffset();
return meta == null ? null : meta.getPaginationOffset();
}

public Integer getPaginationTotal() {
return meta.getPaginationTotal();
return meta == null ? null : meta.getPaginationTotal();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.ibanity.apis.client.jsonapi.isabel_connect;

import com.ibanity.apis.client.jsonapi.RelationshipsApiModel;
import lombok.*;

import java.util.Map;
Expand All @@ -18,4 +19,6 @@ public class DataApiModel {

@Builder.Default
private Map<String, Object> attributes = emptyMap();
@Builder.Default
private Map<String, RelationshipsApiModel> relationships = emptyMap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ public class MetaApiModel {
private PagingApiModel paging;

public Integer getPaginationOffset() {
return paging.getOffset();
return paging == null ? null : paging.getOffset();
}

public Integer getPaginationTotal() {
return paging.getTotal();
return paging == null ? null : paging.getTotal();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.ibanity.apis.client.products.isabel_connect.models;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

import java.time.Instant;

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PaymentNotification extends IsabelModel<String> {
public static final String RESOURCE_TYPE = "paymentNotification";

private String notificationType;
private Instant createdAt;
private String paymentId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.ibanity.apis.client.products.isabel_connect.models.delete;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.Map;

import static java.util.Collections.emptyMap;

@Getter
@Builder
@ToString
@EqualsAndHashCode
public class PaymentNotificationDeleteQuery {
private String accessToken;
private String paymentNotificationId;

@Builder.Default
private Map<String, String> additionalHeaders = emptyMap();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.ibanity.apis.client.products.isabel_connect.models.read;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.Map;

import static java.util.Collections.emptyMap;

@Getter
@Builder
@ToString
@EqualsAndHashCode
public class PaymentNotificationsReadQuery {
private String accessToken;
private IsabelPagingSpec pagingSpec;

@Builder.Default
private Map<String, String> additionalHeaders = emptyMap();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.ibanity.apis.client.products.isabel_connect.models.read;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

import java.util.Map;

import static java.util.Collections.emptyMap;

@Getter
@Builder
@ToString
@EqualsAndHashCode
public class PaymentStatusReadQuery {
private String accessToken;
private String bulkPaymentInitiationRequestId;
private String notificationId;

@Builder.Default
private Map<String, String> additionalHeaders = emptyMap();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,8 @@ public interface IsabelConnectService {
TransactionService transactionService();

TokenService tokenService();

PaymentNotificationService paymentNotificationService();

PaymentStatusService paymentStatusService();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ibanity.apis.client.products.isabel_connect.services;

import com.ibanity.apis.client.models.IsabelCollection;
import com.ibanity.apis.client.products.isabel_connect.models.PaymentNotification;
import com.ibanity.apis.client.products.isabel_connect.models.delete.PaymentNotificationDeleteQuery;
import com.ibanity.apis.client.products.isabel_connect.models.read.PaymentNotificationsReadQuery;

public interface PaymentNotificationService {
IsabelCollection<PaymentNotification> list(PaymentNotificationsReadQuery query);
void delete(PaymentNotificationDeleteQuery query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ibanity.apis.client.products.isabel_connect.services;

import com.ibanity.apis.client.products.isabel_connect.models.read.PaymentStatusReadQuery;

public interface PaymentStatusService {
String find(PaymentStatusReadQuery query);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class IsabelConnectServiceImpl implements IsabelConnectService {
private final IntradayTransactionService intradayTransactionService;
private final TransactionService transactionService;
private final TokenService tokenService;
private final PaymentNotificationService paymentNotificationService;
private final PaymentStatusService paymentStatusService;

public IsabelConnectServiceImpl(
ApiUrlProvider apiUrlProvider,
Expand All @@ -26,6 +28,8 @@ public IsabelConnectServiceImpl(
transactionService = new TransactionServiceImpl(apiUrlProvider, ibanityHttpClient);
tokenService = new TokenServiceImpl(apiUrlProvider, oAuthHttpClient);
bulkPaymentInitiationRequestService = new BulkPaymentInitiationRequestServiceImpl(apiUrlProvider, new IbanityResponseHandler(), ibanityHttpClient);
paymentNotificationService = new PaymentNotificationServiceImpl(apiUrlProvider, ibanityHttpClient);
paymentStatusService = new PaymentStatusServiceImpl(apiUrlProvider, ibanityHttpClient);
}

@Override
Expand All @@ -48,4 +52,10 @@ public IsabelConnectServiceImpl(

@Override
public TokenService tokenService() { return tokenService; }

@Override
public PaymentNotificationService paymentNotificationService() { return paymentNotificationService; }

@Override
public PaymentStatusService paymentStatusService() { return paymentStatusService; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.ibanity.apis.client.products.isabel_connect.services.impl;

import com.ibanity.apis.client.http.IbanityHttpClient;
import com.ibanity.apis.client.jsonapi.RelationshipsApiModel;
import com.ibanity.apis.client.jsonapi.isabel_connect.DataApiModel;
import com.ibanity.apis.client.mappers.IsabelModelMapper;
import com.ibanity.apis.client.models.IbanityProduct;
import com.ibanity.apis.client.models.IsabelCollection;
import com.ibanity.apis.client.products.isabel_connect.models.PaymentNotification;
import com.ibanity.apis.client.products.isabel_connect.models.delete.PaymentNotificationDeleteQuery;
import com.ibanity.apis.client.products.isabel_connect.models.read.PaymentNotificationsReadQuery;
import com.ibanity.apis.client.products.isabel_connect.services.PaymentNotificationService;
import com.ibanity.apis.client.services.ApiUrlProvider;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;

import java.net.URI;
import java.util.Optional;

import static com.ibanity.apis.client.utils.URIHelper.buildUri;

public class PaymentNotificationServiceImpl implements PaymentNotificationService {
private final ApiUrlProvider apiUrlProvider;
private final IbanityHttpClient ibanityHttpClient;

public PaymentNotificationServiceImpl(ApiUrlProvider apiUrlProvider, IbanityHttpClient ibanityHttpClient) {
this.apiUrlProvider = apiUrlProvider;
this.ibanityHttpClient = ibanityHttpClient;
}

@Override
public IsabelCollection<PaymentNotification> list(PaymentNotificationsReadQuery query) {
URI uri = buildUri(getNotificationsUrl(), query.getPagingSpec());
HttpResponse response = ibanityHttpClient.get(uri, query.getAdditionalHeaders(), query.getAccessToken());
return IsabelModelMapper.mapCollection(response, data -> {
PaymentNotification notification = IsabelModelMapper.toIsabelModel(data, PaymentNotification.class);
notification.setPaymentId(extractPaymentId(data));
return notification;
});
}

@Override
public void delete(PaymentNotificationDeleteQuery query) {
URI uri = buildUri(getNotificationUrl(query.getPaymentNotificationId()));
ibanityHttpClient.delete(uri, query.getAdditionalHeaders(), query.getAccessToken());
}

private String extractPaymentId(DataApiModel data) {
return Optional.ofNullable(data.getRelationships())
.map(relationships -> relationships.get("payment"))
.map(RelationshipsApiModel::getData)
.map(paymentData -> paymentData.getId())
.orElse(null);
}

private String getNotificationsUrl() {
String url = apiUrlProvider
.find(IbanityProduct.IsabelConnect, "bulkPaymentInitiationRequests")
.replace("{bulkPaymentInitiationRequestId}", "notifications");
return StringUtils.removeEnd(url, "/");
}

private String getNotificationUrl(String paymentNotificationId) {
String url = apiUrlProvider
.find(IbanityProduct.IsabelConnect, "bulkPaymentInitiationRequests")
.replace("{bulkPaymentInitiationRequestId}", "notifications/" + paymentNotificationId);
return StringUtils.removeEnd(url, "/");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.ibanity.apis.client.products.isabel_connect.services.impl;

import com.ibanity.apis.client.http.IbanityHttpClient;
import com.ibanity.apis.client.models.IbanityProduct;
import com.ibanity.apis.client.products.isabel_connect.models.read.IsabelPagingSpec;
import com.ibanity.apis.client.products.isabel_connect.models.read.PaymentStatusReadQuery;
import com.ibanity.apis.client.products.isabel_connect.services.PaymentStatusService;
import com.ibanity.apis.client.services.ApiUrlProvider;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;

import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import static com.ibanity.apis.client.mappers.ModelMapperHelper.readResponseContent;
import static com.ibanity.apis.client.utils.URIHelper.buildUri;

public class PaymentStatusServiceImpl implements PaymentStatusService {
private final ApiUrlProvider apiUrlProvider;
private final IbanityHttpClient ibanityHttpClient;

public PaymentStatusServiceImpl(ApiUrlProvider apiUrlProvider, IbanityHttpClient ibanityHttpClient) {
this.apiUrlProvider = apiUrlProvider;
this.ibanityHttpClient = ibanityHttpClient;
}

@Override
public String find(PaymentStatusReadQuery query) {
Map<String, String> queryParams = new HashMap<>();
if (StringUtils.isNotBlank(query.getNotificationId())) {
queryParams.put("notificationId", query.getNotificationId());
}
IsabelPagingSpec emptyPagingSpec = IsabelPagingSpec.builder().size(null).build();
URI uri = buildUri(getUrl(query.getBulkPaymentInitiationRequestId()), emptyPagingSpec, queryParams);
HttpResponse response = ibanityHttpClient.get(uri, query.getAdditionalHeaders(), query.getAccessToken());
try {
return readResponseContent(response.getEntity());
} catch (IOException exception) {
throw new IllegalArgumentException("Response cannot be parsed", exception);
}
}

private String getUrl(String bulkPaymentInitiationRequestId) {
String url = apiUrlProvider
.find(IbanityProduct.IsabelConnect, "bulkPaymentInitiationRequests")
.replace("{bulkPaymentInitiationRequestId}", bulkPaymentInitiationRequestId);
return StringUtils.removeEnd(url, "/") + "/payment-status";
}
}
12 changes: 12 additions & 0 deletions src/main/java/com/ibanity/apis/client/utils/WebhooksUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ibanity.apis.client.exceptions.IbanityRuntimeException;
import com.ibanity.apis.client.models.IbanityWebhookEvent;
import com.ibanity.apis.client.webhooks.models.isabel_connect.PaymentStatusUpdated;
import com.ibanity.apis.client.webhooks.models.xs2a.*;
import org.apache.commons.codec.digest.MessageDigestAlgorithms;

Expand Down Expand Up @@ -46,6 +47,8 @@ public static String getDigest(String payload) {
public static IbanityWebhookEvent webhookEventParser(String payload, String type) {
if (type.contains("xs2a.")) {
return parseXs2aEvent(payload, type);
} else if (type.contains("isabelConnect.")) {
return parseIsabelConnectEvent(payload, type);
} else {
return parsePontoConnectEvent(payload, type);
}
Expand Down Expand Up @@ -122,4 +125,13 @@ private static IbanityWebhookEvent parsePontoConnectEvent(String payload, String

throw new IbanityRuntimeException(format("Event Type not handled by the java library \"%s\".", type));
}

private static IbanityWebhookEvent parseIsabelConnectEvent(String payload, String type) {
switch (type) {
case PaymentStatusUpdated.TYPE:
return mapWebhookResource(payload, PaymentStatusUpdated.mappingFunction());
}

throw new IbanityRuntimeException(format("Event Type not handled by the java library \"%s\".", type));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.ibanity.apis.client.webhooks.models.isabel_connect;

import com.ibanity.apis.client.jsonapi.DataApiModel;
import com.ibanity.apis.client.jsonapi.RelationshipsApiModel;
import com.ibanity.apis.client.models.IbanityWebhookEvent;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.time.Instant;
import java.util.UUID;
import java.util.function.Function;

import static com.ibanity.apis.client.mappers.IbanityWebhookEventMapper.toIbanityWebhooks;

@Data
@SuperBuilder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class PaymentStatusUpdated implements IbanityWebhookEvent {

public final static String TYPE = "isabelConnect.payment.status.updated";

private UUID id;
private String type;
private String notificationType;
private Instant createdAt;
private String paymentId;

public static Function<DataApiModel, PaymentStatusUpdated> mappingFunction() {
return dataApiModel -> {
PaymentStatusUpdated paymentStatusUpdated = toIbanityWebhooks(dataApiModel, PaymentStatusUpdated.class);

RelationshipsApiModel paymentRelationship = dataApiModel.getRelationships().get("payment");
if (paymentRelationship != null) {
paymentStatusUpdated.setPaymentId(paymentRelationship.getData().getId());
}

return paymentStatusUpdated;
};
}
}
Loading
Loading