diff --git a/README.md b/README.md index 041e690f..6dc520a5 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,14 @@ With Maven: com.gocardless gocardless-pro - 5.24.0 + 5.25.0 ``` With Gradle: ``` -implementation 'com.gocardless:gocardless-pro:5.24.0' +implementation 'com.gocardless:gocardless-pro:5.25.0' ``` ## Initializing the client diff --git a/build.gradle b/build.gradle index 305edffc..95dfc31f 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ plugins { sourceCompatibility = 1.8 targetCompatibility = 1.8 group = 'com.gocardless' -version = '5.24.0' +version = '5.25.0' apply plugin: 'ch.raffael.pegdown-doclet' diff --git a/src/main/java/com/gocardless/GoCardlessClient.java b/src/main/java/com/gocardless/GoCardlessClient.java index 1efa4679..11a66816 100644 --- a/src/main/java/com/gocardless/GoCardlessClient.java +++ b/src/main/java/com/gocardless/GoCardlessClient.java @@ -29,12 +29,14 @@ public class GoCardlessClient { private final EventService events; private final InstalmentScheduleService instalmentSchedules; private final InstitutionService institutions; + private final LogoService logos; private final MandateService mandates; private final MandateImportService mandateImports; private final MandateImportEntryService mandateImportEntries; private final MandatePdfService mandatePdfs; private final NegativeBalanceLimitService negativeBalanceLimits; private final PayerAuthorisationService payerAuthorisations; + private final PayerThemeService payerThemes; private final PaymentService payments; private final PayoutService payouts; private final PayoutItemService payoutItems; @@ -183,12 +185,14 @@ private GoCardlessClient(HttpClient httpClient) { this.events = new EventService(httpClient); this.instalmentSchedules = new InstalmentScheduleService(httpClient); this.institutions = new InstitutionService(httpClient); + this.logos = new LogoService(httpClient); this.mandates = new MandateService(httpClient); this.mandateImports = new MandateImportService(httpClient); this.mandateImportEntries = new MandateImportEntryService(httpClient); this.mandatePdfs = new MandatePdfService(httpClient); this.negativeBalanceLimits = new NegativeBalanceLimitService(httpClient); this.payerAuthorisations = new PayerAuthorisationService(httpClient); + this.payerThemes = new PayerThemeService(httpClient); this.payments = new PaymentService(httpClient); this.payouts = new PayoutService(httpClient); this.payoutItems = new PayoutItemService(httpClient); @@ -308,6 +312,13 @@ public InstitutionService institutions() { return institutions; } + /** + * A service class for working with logo resources. + */ + public LogoService logos() { + return logos; + } + /** * A service class for working with mandate resources. */ @@ -350,6 +361,13 @@ public PayerAuthorisationService payerAuthorisations() { return payerAuthorisations; } + /** + * A service class for working with payer theme resources. + */ + public PayerThemeService payerThemes() { + return payerThemes; + } + /** * A service class for working with payment resources. */ diff --git a/src/main/java/com/gocardless/http/HttpClient.java b/src/main/java/com/gocardless/http/HttpClient.java index 2a5927fc..11d428a0 100644 --- a/src/main/java/com/gocardless/http/HttpClient.java +++ b/src/main/java/com/gocardless/http/HttpClient.java @@ -35,7 +35,7 @@ public class HttpClient { private static final String DISALLOWED_USER_AGENT_CHARACTERS = "[^\\w!#$%&'\\*\\+\\-\\.\\^`\\|~]"; private static final String USER_AGENT = - String.format("gocardless-pro-java/5.24.0 java/%s %s/%s %s/%s", + String.format("gocardless-pro-java/5.25.0 java/%s %s/%s %s/%s", cleanUserAgentToken(System.getProperty("java.vm.specification.version")), cleanUserAgentToken(System.getProperty("java.vm.name")), cleanUserAgentToken(System.getProperty("java.version")), @@ -49,7 +49,7 @@ public class HttpClient { builder.put("GoCardless-Version", "2015-07-06"); builder.put("Accept", "application/json"); builder.put("GoCardless-Client-Library", "gocardless-pro-java"); - builder.put("GoCardless-Client-Version", "5.24.0"); + builder.put("GoCardless-Client-Version", "5.25.0"); HEADERS = builder.build(); } private final OkHttpClient rawClient; diff --git a/src/main/java/com/gocardless/resources/BillingRequest.java b/src/main/java/com/gocardless/resources/BillingRequest.java index 8776727e..1bb28a92 100644 --- a/src/main/java/com/gocardless/resources/BillingRequest.java +++ b/src/main/java/com/gocardless/resources/BillingRequest.java @@ -755,6 +755,7 @@ private PaymentRequest() { private Integer appFee; private String currency; private String description; + private FundsSettlement fundsSettlement; private Links links; private Map metadata; private String scheme; @@ -793,6 +794,18 @@ public String getDescription() { return description; } + /** + * This field will decide how GoCardless handles settlement of funds from the customer. + * + * - `managed` will be moved through GoCardless' account, batched, and payed out. - `direct` + * will be a direct transfer from the payer's account to the merchant where invoicing will + * be handled separately. + * + */ + public FundsSettlement getFundsSettlement() { + return fundsSettlement; + } + public Links getLinks() { return links; } @@ -816,6 +829,13 @@ public String getScheme() { return scheme; } + public enum FundsSettlement { + @SerializedName("managed") + MANAGED, @SerializedName("direct") + DIRECT, @SerializedName("unknown") + UNKNOWN + } + public static class Links { private Links() { // blank to prevent instantiation diff --git a/src/main/java/com/gocardless/resources/Logo.java b/src/main/java/com/gocardless/resources/Logo.java new file mode 100644 index 00000000..326038b9 --- /dev/null +++ b/src/main/java/com/gocardless/resources/Logo.java @@ -0,0 +1,22 @@ +package com.gocardless.resources; + +/** + * Represents a logo resource returned from the API. + * + * Logos are image uploads that, when associated with a creditor, are shown on the [billing request + * flow](#billing-requests-billing-request-flows) payment pages. + */ +public class Logo { + private Logo() { + // blank to prevent instantiation + } + + private String id; + + /** + * Unique identifier, beginning with "LO". + */ + public String getId() { + return id; + } +} diff --git a/src/main/java/com/gocardless/resources/PayerTheme.java b/src/main/java/com/gocardless/resources/PayerTheme.java new file mode 100644 index 00000000..354fba49 --- /dev/null +++ b/src/main/java/com/gocardless/resources/PayerTheme.java @@ -0,0 +1,21 @@ +package com.gocardless.resources; + +/** + * Represents a payer theme resource returned from the API. + * + * Custom colour themes for payment pages and customer notifications. + */ +public class PayerTheme { + private PayerTheme() { + // blank to prevent instantiation + } + + private String id; + + /** + * Unique identifier, beginning with "PTH". + */ + public String getId() { + return id; + } +} diff --git a/src/main/java/com/gocardless/resources/Subscription.java b/src/main/java/com/gocardless/resources/Subscription.java index 36d03ea2..f3327927 100644 --- a/src/main/java/com/gocardless/resources/Subscription.java +++ b/src/main/java/com/gocardless/resources/Subscription.java @@ -40,7 +40,6 @@ * - if the recurrence rule specified `-1` as the `day_of_month`, the charge date will be rolled * __backwards__ to the previous business day (i.e., the last working day of the month). - otherwise * the charge date will be rolled __forwards__ to the next business day. - * */ public class Subscription { private Subscription() { diff --git a/src/main/java/com/gocardless/services/BankDetailsLookupService.java b/src/main/java/com/gocardless/services/BankDetailsLookupService.java index e681e975..f6336246 100644 --- a/src/main/java/com/gocardless/services/BankDetailsLookupService.java +++ b/src/main/java/com/gocardless/services/BankDetailsLookupService.java @@ -24,6 +24,10 @@ public BankDetailsLookupService(HttpClient httpClient) { * Performs a bank details lookup. As part of the lookup, a modulus check and reachability check * are performed. * + * For UK-based bank accounts, where an account holder name is provided (and an account number, + * a sort code or an iban are already present), we verify that the account holder name and bank + * account number match the details held by the relevant bank. + * * If your request returns an [error](#api-usage-errors) or the `available_debit_schemes` * attribute is an empty array, you will not be able to collect payments from the specified bank * account. GoCardless may be able to collect payments from an account even if no `bic` is @@ -50,6 +54,10 @@ public BankDetailsLookupCreateRequest create() { * Performs a bank details lookup. As part of the lookup, a modulus check and reachability check * are performed. * + * For UK-based bank accounts, where an account holder name is provided (and an account number, + * a sort code or an iban are already present), we verify that the account holder name and bank + * account number match the details held by the relevant bank. + * * If your request returns an [error](#api-usage-errors) or the `available_debit_schemes` * attribute is an empty array, you will not be able to collect payments from the specified bank * account. GoCardless may be able to collect payments from an account even if no `bic` is @@ -68,12 +76,22 @@ public BankDetailsLookupCreateRequest create() { */ public static final class BankDetailsLookupCreateRequest extends PostRequest { + private String accountHolderName; private String accountNumber; private String bankCode; private String branchCode; private String countryCode; private String iban; + /** + * The account holder name associated with the account number (if available). If provided + * and the country code is GB, a payer name verification will be performed. + */ + public BankDetailsLookupCreateRequest withAccountHolderName(String accountHolderName) { + this.accountHolderName = accountHolderName; + return this; + } + /** * Bank account number - see [local details](#appendix-local-bank-details) for more * information. Alternatively you can provide an `iban`. diff --git a/src/main/java/com/gocardless/services/BillingRequestService.java b/src/main/java/com/gocardless/services/BillingRequestService.java index ce121ddf..219b2ec7 100644 --- a/src/main/java/com/gocardless/services/BillingRequestService.java +++ b/src/main/java/com/gocardless/services/BillingRequestService.java @@ -66,6 +66,11 @@ public BillingRequestCollectCustomerDetailsRequest collectCustomerDetails(String * provider to make sure the customer's bank account can accept Direct Debit. If a bank account * is discovered to be closed or invalid, the customer is requested to adjust the account * number/routing number and succeed in this check to continue with the flow. + * + * _BACS scheme_ [Payer Name + * Verification](https://hub.gocardless.com/s/article/Introduction-to-Payer-Name-Verification?language=en_GB) + * is enabled by default for UK based bank accounts, meaning we verify the account holder name + * and bank account number match the details held by the relevant bank. */ public BillingRequestCollectBankAccountRequest collectBankAccount(String identity) { return new BillingRequestCollectBankAccountRequest(httpClient, identity); @@ -426,6 +431,23 @@ public BillingRequestCreateRequest withPaymentRequestDescription(String descript return this; } + /** + * This field will decide how GoCardless handles settlement of funds from the customer. + * + * - `managed` will be moved through GoCardless' account, batched, and payed out. - `direct` + * will be a direct transfer from the payer's account to the merchant where invoicing will + * be handled separately. + * + */ + public BillingRequestCreateRequest withPaymentRequestFundsSettlement( + PaymentRequest.FundsSettlement fundsSettlement) { + if (paymentRequest == null) { + paymentRequest = new PaymentRequest(); + } + paymentRequest.withFundsSettlement(fundsSettlement); + return this; + } + /** * Key-value store of custom data. Up to 3 keys are permitted, with key names up to 50 * characters and values up to 500 characters. @@ -871,6 +893,7 @@ public static class PaymentRequest { private Integer appFee; private String currency; private String description; + private FundsSettlement fundsSettlement; private Map metadata; private String scheme; @@ -912,6 +935,19 @@ public PaymentRequest withDescription(String description) { return this; } + /** + * This field will decide how GoCardless handles settlement of funds from the customer. + * + * - `managed` will be moved through GoCardless' account, batched, and payed out. - + * `direct` will be a direct transfer from the payer's account to the merchant where + * invoicing will be handled separately. + * + */ + public PaymentRequest withFundsSettlement(FundsSettlement fundsSettlement) { + this.fundsSettlement = fundsSettlement; + return this; + } + /** * Key-value store of custom data. Up to 3 keys are permitted, with key names up to 50 * characters and values up to 500 characters. @@ -932,6 +968,18 @@ public PaymentRequest withScheme(String scheme) { this.scheme = scheme; return this; } + + public enum FundsSettlement { + @SerializedName("managed") + MANAGED, @SerializedName("direct") + DIRECT, @SerializedName("unknown") + UNKNOWN; + + @Override + public String toString() { + return name().toLowerCase(); + } + } } } @@ -1434,6 +1482,11 @@ public CustomerBillingDetail withSwedishIdentityNumber(String swedishIdentityNum * provider to make sure the customer's bank account can accept Direct Debit. If a bank account * is discovered to be closed or invalid, the customer is requested to adjust the account * number/routing number and succeed in this check to continue with the flow. + * + * _BACS scheme_ [Payer Name + * Verification](https://hub.gocardless.com/s/article/Introduction-to-Payer-Name-Verification?language=en_GB) + * is enabled by default for UK based bank accounts, meaning we verify the account holder name + * and bank account number match the details held by the relevant bank. */ public static final class BillingRequestCollectBankAccountRequest extends PostRequest { diff --git a/src/main/java/com/gocardless/services/LogoService.java b/src/main/java/com/gocardless/services/LogoService.java new file mode 100644 index 00000000..052cf777 --- /dev/null +++ b/src/main/java/com/gocardless/services/LogoService.java @@ -0,0 +1,106 @@ +package com.gocardless.services; + +import com.gocardless.http.*; +import com.gocardless.resources.Logo; + +/** + * Service class for working with logo resources. + * + * Logos are image uploads that, when associated with a creditor, are shown on the [billing request + * flow](#billing-requests-billing-request-flows) payment pages. + */ +public class LogoService { + private final HttpClient httpClient; + + /** + * Constructor. Users of this library should have no need to call this - an instance of this + * class can be obtained by calling {@link com.gocardless.GoCardlessClient#logos() }. + */ + public LogoService(HttpClient httpClient) { + this.httpClient = httpClient; + } + + /** + * Creates a new logo associated with a creditor. If a creditor already has a logo, this will + * update the existing logo linked to the creditor. + */ + public LogoCreateForCreditorRequest createForCreditor() { + return new LogoCreateForCreditorRequest(httpClient); + } + + /** + * Request class for {@link LogoService#createForCreditor }. + * + * Creates a new logo associated with a creditor. If a creditor already has a logo, this will + * update the existing logo linked to the creditor. + */ + public static final class LogoCreateForCreditorRequest extends PostRequest { + private String image; + private Links links; + + /** + * Base64 encoded string. + */ + public LogoCreateForCreditorRequest withImage(String image) { + this.image = image; + return this; + } + + public LogoCreateForCreditorRequest withLinks(Links links) { + this.links = links; + return this; + } + + /** + * ID of the creditor the payer theme belongs to + */ + public LogoCreateForCreditorRequest withLinksCreditor(String creditor) { + if (links == null) { + links = new Links(); + } + links.withCreditor(creditor); + return this; + } + + private LogoCreateForCreditorRequest(HttpClient httpClient) { + super(httpClient); + } + + public LogoCreateForCreditorRequest withHeader(String headerName, String headerValue) { + this.addHeader(headerName, headerValue); + return this; + } + + @Override + protected String getPathTemplate() { + return "branding/logos"; + } + + @Override + protected String getEnvelope() { + return "logos"; + } + + @Override + protected Class getResponseClass() { + return Logo.class; + } + + @Override + protected boolean hasBody() { + return true; + } + + public static class Links { + private String creditor; + + /** + * ID of the creditor the payer theme belongs to + */ + public Links withCreditor(String creditor) { + this.creditor = creditor; + return this; + } + } + } +} diff --git a/src/main/java/com/gocardless/services/PayerThemeService.java b/src/main/java/com/gocardless/services/PayerThemeService.java new file mode 100644 index 00000000..d41183c0 --- /dev/null +++ b/src/main/java/com/gocardless/services/PayerThemeService.java @@ -0,0 +1,136 @@ +package com.gocardless.services; + +import com.gocardless.http.*; +import com.gocardless.resources.PayerTheme; + +/** + * Service class for working with payer theme resources. + * + * Custom colour themes for payment pages and customer notifications. + */ +public class PayerThemeService { + private final HttpClient httpClient; + + /** + * Constructor. Users of this library should have no need to call this - an instance of this + * class can be obtained by calling {@link com.gocardless.GoCardlessClient#payerThemes() }. + */ + public PayerThemeService(HttpClient httpClient) { + this.httpClient = httpClient; + } + + /** + * Creates a new payer theme associated with a creditor. If a creditor already has payer themes, + * this will update the existing payer theme linked to the creditor. + */ + public PayerThemeCreateForCreditorRequest createForCreditor() { + return new PayerThemeCreateForCreditorRequest(httpClient); + } + + /** + * Request class for {@link PayerThemeService#createForCreditor }. + * + * Creates a new payer theme associated with a creditor. If a creditor already has payer themes, + * this will update the existing payer theme linked to the creditor. + */ + public static final class PayerThemeCreateForCreditorRequest extends PostRequest { + private String buttonBackgroundColour; + private String contentBoxBorderColour; + private String headerBackgroundColour; + private String linkTextColour; + private Links links; + + /** + * Colour for buttons background (hexcode) + */ + public PayerThemeCreateForCreditorRequest withButtonBackgroundColour( + String buttonBackgroundColour) { + this.buttonBackgroundColour = buttonBackgroundColour; + return this; + } + + /** + * Colour for content box border (hexcode) + */ + public PayerThemeCreateForCreditorRequest withContentBoxBorderColour( + String contentBoxBorderColour) { + this.contentBoxBorderColour = contentBoxBorderColour; + return this; + } + + /** + * Colour for header background (hexcode) + */ + public PayerThemeCreateForCreditorRequest withHeaderBackgroundColour( + String headerBackgroundColour) { + this.headerBackgroundColour = headerBackgroundColour; + return this; + } + + /** + * Colour for text links (hexcode) + */ + public PayerThemeCreateForCreditorRequest withLinkTextColour(String linkTextColour) { + this.linkTextColour = linkTextColour; + return this; + } + + public PayerThemeCreateForCreditorRequest withLinks(Links links) { + this.links = links; + return this; + } + + /** + * ID of the creditor the payer theme belongs to + */ + public PayerThemeCreateForCreditorRequest withLinksCreditor(String creditor) { + if (links == null) { + links = new Links(); + } + links.withCreditor(creditor); + return this; + } + + private PayerThemeCreateForCreditorRequest(HttpClient httpClient) { + super(httpClient); + } + + public PayerThemeCreateForCreditorRequest withHeader(String headerName, + String headerValue) { + this.addHeader(headerName, headerValue); + return this; + } + + @Override + protected String getPathTemplate() { + return "branding/payer_themes"; + } + + @Override + protected String getEnvelope() { + return "payer_themes"; + } + + @Override + protected Class getResponseClass() { + return PayerTheme.class; + } + + @Override + protected boolean hasBody() { + return true; + } + + public static class Links { + private String creditor; + + /** + * ID of the creditor the payer theme belongs to + */ + public Links withCreditor(String creditor) { + this.creditor = creditor; + return this; + } + } + } +} diff --git a/src/main/java/com/gocardless/services/SubscriptionService.java b/src/main/java/com/gocardless/services/SubscriptionService.java index eac266ea..22d8d595 100644 --- a/src/main/java/com/gocardless/services/SubscriptionService.java +++ b/src/main/java/com/gocardless/services/SubscriptionService.java @@ -47,7 +47,6 @@ * - if the recurrence rule specified `-1` as the `day_of_month`, the charge date will be rolled * __backwards__ to the previous business day (i.e., the last working day of the month). - otherwise * the charge date will be rolled __forwards__ to the next business day. - * */ public class SubscriptionService { private final HttpClient httpClient; @@ -151,7 +150,6 @@ public SubscriptionUpdateRequest update(String identity) { * * - `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for `pause_cycles` * cannot be satisfied. - * */ public SubscriptionPauseRequest pause(String identity) { return new SubscriptionPauseRequest(httpClient, identity); @@ -941,7 +939,6 @@ protected boolean hasBody() { * * - `pause_cycles_must_be_greater_than_or_equal_to` if the provided value for `pause_cycles` * cannot be satisfied. - * */ public static final class SubscriptionPauseRequest extends PostRequest { @PathParam @@ -972,7 +969,11 @@ public SubscriptionPauseRequest withMetadata(String key, String value) { /** * The number of cycles to pause a subscription for. A cycle is one duration of `interval` - * and `interval_unit`. This should be a non zero positive value. + * and `interval_unit`. This should be a non zero positive value. For AUD subscriptions with + * `interval_unit: weekly` the minimum value varies between `3` & `4` because of the + * [mandatory minimum waiting period](#subscriptions-resume-a-subscription). For NZD + * subscriptions with `interval_unit: weekly` the minimum value is `2` because of the + * [mandatory minimum waiting period](#subscriptions-resume-a-subscription). */ public SubscriptionPauseRequest withPauseCycles(Integer pauseCycles) { this.pauseCycles = pauseCycles;