All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gocardless.services.RefundService Maven / Gradle / Ivy

There is a newer version: 6.0.0
Show newest version
package com.gocardless.services;

import com.gocardless.http.*;
import com.gocardless.resources.Refund;
import com.google.common.collect.ImmutableMap;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Service class for working with refund resources.
 *
 * Refund objects represent (partial) refunds of a [payment](#core-endpoints-payments) back to the
 * [customer](#core-endpoints-customers).
 * 
 * GoCardless will notify you via a [webhook](#appendix-webhooks) whenever a refund is created, and
 * will update the `amount_refunded` property of the payment.
 */
public class RefundService {
    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#refunds() }.
     */
    public RefundService(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    /**
     * Creates a new refund object.
     * 
     * This fails with:
     * 
     * - `total_amount_confirmation_invalid` if the confirmation amount doesn't match the total
     * amount refunded for the payment. This safeguard is there to prevent two processes from
     * creating refunds without awareness of each other.
     * 
     * - `number_of_refunds_exceeded` if five or more refunds have already been created against the
     * payment.
     * 
     * - `available_refund_amount_insufficient` if the creditor does not have sufficient balance for
     * refunds available to cover the cost of the requested refund.
     * 
     */
    public RefundCreateRequest create() {
        return new RefundCreateRequest(httpClient);
    }

    /**
     * Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your refunds.
     */
    public RefundListRequest> list() {
        return new RefundListRequest<>(httpClient, ListRequest.pagingExecutor());
    }

    public RefundListRequest> all() {
        return new RefundListRequest<>(httpClient, ListRequest.iteratingExecutor());
    }

    /**
     * Retrieves all details for a single refund
     */
    public RefundGetRequest get(String identity) {
        return new RefundGetRequest(httpClient, identity);
    }

    /**
     * Updates a refund object.
     */
    public RefundUpdateRequest update(String identity) {
        return new RefundUpdateRequest(httpClient, identity);
    }

    /**
     * Request class for {@link RefundService#create }.
     *
     * Creates a new refund object.
     * 
     * This fails with:
     * 
     * - `total_amount_confirmation_invalid` if the confirmation amount doesn't match the total
     * amount refunded for the payment. This safeguard is there to prevent two processes from
     * creating refunds without awareness of each other.
     * 
     * - `number_of_refunds_exceeded` if five or more refunds have already been created against the
     * payment.
     * 
     * - `available_refund_amount_insufficient` if the creditor does not have sufficient balance for
     * refunds available to cover the cost of the requested refund.
     * 
     */
    public static final class RefundCreateRequest extends IdempotentPostRequest {
        private Integer amount;
        private Links links;
        private Map metadata;
        private String reference;
        private Integer totalAmountConfirmation;

        /**
         * Amount in minor unit (e.g. pence in GBP, cents in EUR).
         */
        public RefundCreateRequest withAmount(Integer amount) {
            this.amount = amount;
            return this;
        }

        public RefundCreateRequest withLinks(Links links) {
            this.links = links;
            return this;
        }

        /**
         * ID of the [mandate](#core-endpoints-mandates) against which the refund is being made.
         * 
*

* Restricted: You must request access to Mandate Refunds by contacting * our support team. *

*/ public RefundCreateRequest withLinksMandate(String mandate) { if (links == null) { links = new Links(); } links.withMandate(mandate); return this; } /** * ID of the [payment](#core-endpoints-payments) against which the refund is being made. */ public RefundCreateRequest withLinksPayment(String payment) { if (links == null) { links = new Links(); } links.withPayment(payment); 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. */ public RefundCreateRequest withMetadata(Map metadata) { this.metadata = metadata; 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. */ public RefundCreateRequest withMetadata(String key, String value) { if (metadata == null) { metadata = new HashMap<>(); } metadata.put(key, value); return this; } /** * An optional reference that will appear on your customer's bank statement. The character * limit for this reference is dependent on the scheme.
* ACH - 10 characters
* Autogiro - 11 characters
* Bacs - 10 characters
* BECS - 30 characters
* BECS NZ - 12 characters
* Betalingsservice - 30 characters
* Faster Payments - 18 characters
* PAD - scheme doesn't offer references
* PayTo - 18 characters
* SEPA - 140 characters
* Note that this reference must be unique (for each merchant) for the BECS scheme as it is * a scheme requirement. *

* Restricted: You can only specify a payment reference for Bacs payments * (that is, when collecting from the UK) if you're on the * GoCardless Plus, Pro or Enterprise packages. *

*

* Restricted: You can not specify a payment reference for Faster Payments. *

*/ public RefundCreateRequest withReference(String reference) { this.reference = reference; return this; } /** * Total expected refunded amount in minor unit (e.g. pence/cents/öre). If there are other * partial refunds against this payment, this value should be the sum of the existing * refunds plus the amount of the refund being created.
* Must be supplied if `links[payment]` is present. */ public RefundCreateRequest withTotalAmountConfirmation(Integer totalAmountConfirmation) { this.totalAmountConfirmation = totalAmountConfirmation; return this; } public RefundCreateRequest withIdempotencyKey(String idempotencyKey) { super.setIdempotencyKey(idempotencyKey); return this; } @Override protected GetRequest handleConflict(HttpClient httpClient, String id) { RefundGetRequest request = new RefundGetRequest(httpClient, id); for (Map.Entry header : this.getCustomHeaders().entrySet()) { request = request.withHeader(header.getKey(), header.getValue()); } return request; } private RefundCreateRequest(HttpClient httpClient) { super(httpClient); } public RefundCreateRequest withHeader(String headerName, String headerValue) { this.addHeader(headerName, headerValue); return this; } @Override protected String getPathTemplate() { return "refunds"; } @Override protected String getEnvelope() { return "refunds"; } @Override protected Class getResponseClass() { return Refund.class; } @Override protected boolean hasBody() { return true; } public static class Links { private String mandate; private String payment; /** * ID of the [mandate](#core-endpoints-mandates) against which the refund is being made. *
*

* Restricted: You must request access to Mandate Refunds by contacting * our support team. *

*/ public Links withMandate(String mandate) { this.mandate = mandate; return this; } /** * ID of the [payment](#core-endpoints-payments) against which the refund is being made. */ public Links withPayment(String payment) { this.payment = payment; return this; } } } /** * Request class for {@link RefundService#list }. * * Returns a [cursor-paginated](#api-usage-cursor-pagination) list of your refunds. */ public static final class RefundListRequest extends ListRequest { private CreatedAt createdAt; private String mandate; private String payment; private RefundType refundType; /** * Cursor pointing to the start of the desired set. */ public RefundListRequest withAfter(String after) { setAfter(after); return this; } /** * Cursor pointing to the end of the desired set. */ public RefundListRequest withBefore(String before) { setBefore(before); return this; } public RefundListRequest withCreatedAt(CreatedAt createdAt) { this.createdAt = createdAt; return this; } /** * Limit to records created after the specified date-time. */ public RefundListRequest withCreatedAtGt(String gt) { if (createdAt == null) { createdAt = new CreatedAt(); } createdAt.withGt(gt); return this; } /** * Limit to records created on or after the specified date-time. */ public RefundListRequest withCreatedAtGte(String gte) { if (createdAt == null) { createdAt = new CreatedAt(); } createdAt.withGte(gte); return this; } /** * Limit to records created before the specified date-time. */ public RefundListRequest withCreatedAtLt(String lt) { if (createdAt == null) { createdAt = new CreatedAt(); } createdAt.withLt(lt); return this; } /** * Limit to records created on or before the specified date-time. */ public RefundListRequest withCreatedAtLte(String lte) { if (createdAt == null) { createdAt = new CreatedAt(); } createdAt.withLte(lte); return this; } /** * Number of records to return. */ public RefundListRequest withLimit(Integer limit) { setLimit(limit); return this; } /** * Unique identifier, beginning with "MD". Note that this prefix may not apply to mandates * created before 2016. */ public RefundListRequest withMandate(String mandate) { this.mandate = mandate; return this; } /** * Unique identifier, beginning with "PM". */ public RefundListRequest withPayment(String payment) { this.payment = payment; return this; } /** * Whether a refund was issued against a mandate or a payment. One of: *
    *
  • `payment`: default returns refunds created against payments only
  • *
  • `mandate`: returns refunds created against mandates only
  • *
*/ public RefundListRequest withRefundType(RefundType refundType) { this.refundType = refundType; return this; } private RefundListRequest(HttpClient httpClient, ListRequestExecutor executor) { super(httpClient, executor); } public RefundListRequest withHeader(String headerName, String headerValue) { this.addHeader(headerName, headerValue); return this; } @Override protected Map getQueryParams() { ImmutableMap.Builder params = ImmutableMap.builder(); params.putAll(super.getQueryParams()); if (createdAt != null) { params.putAll(createdAt.getQueryParams()); } if (mandate != null) { params.put("mandate", mandate); } if (payment != null) { params.put("payment", payment); } if (refundType != null) { params.put("refund_type", refundType); } return params.build(); } @Override protected String getPathTemplate() { return "refunds"; } @Override protected String getEnvelope() { return "refunds"; } @Override protected TypeToken> getTypeToken() { return new TypeToken>() {}; } public enum RefundType { @SerializedName("mandate") MANDATE, @SerializedName("payment") PAYMENT, @SerializedName("unknown") UNKNOWN; @Override public String toString() { return name().toLowerCase(); } } public static class CreatedAt { private String gt; private String gte; private String lt; private String lte; /** * Limit to records created after the specified date-time. */ public CreatedAt withGt(String gt) { this.gt = gt; return this; } /** * Limit to records created on or after the specified date-time. */ public CreatedAt withGte(String gte) { this.gte = gte; return this; } /** * Limit to records created before the specified date-time. */ public CreatedAt withLt(String lt) { this.lt = lt; return this; } /** * Limit to records created on or before the specified date-time. */ public CreatedAt withLte(String lte) { this.lte = lte; return this; } public Map getQueryParams() { ImmutableMap.Builder params = ImmutableMap.builder(); if (gt != null) { params.put("created_at[gt]", gt); } if (gte != null) { params.put("created_at[gte]", gte); } if (lt != null) { params.put("created_at[lt]", lt); } if (lte != null) { params.put("created_at[lte]", lte); } return params.build(); } } } /** * Request class for {@link RefundService#get }. * * Retrieves all details for a single refund */ public static final class RefundGetRequest extends GetRequest { @PathParam private final String identity; private RefundGetRequest(HttpClient httpClient, String identity) { super(httpClient); this.identity = identity; } public RefundGetRequest withHeader(String headerName, String headerValue) { this.addHeader(headerName, headerValue); return this; } @Override protected Map getPathParams() { ImmutableMap.Builder params = ImmutableMap.builder(); params.put("identity", identity); return params.build(); } @Override protected String getPathTemplate() { return "refunds/:identity"; } @Override protected String getEnvelope() { return "refunds"; } @Override protected Class getResponseClass() { return Refund.class; } } /** * Request class for {@link RefundService#update }. * * Updates a refund object. */ public static final class RefundUpdateRequest extends PutRequest { @PathParam private final String identity; private Map metadata; /** * 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. */ public RefundUpdateRequest withMetadata(Map metadata) { this.metadata = metadata; 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. */ public RefundUpdateRequest withMetadata(String key, String value) { if (metadata == null) { metadata = new HashMap<>(); } metadata.put(key, value); return this; } private RefundUpdateRequest(HttpClient httpClient, String identity) { super(httpClient); this.identity = identity; } public RefundUpdateRequest withHeader(String headerName, String headerValue) { this.addHeader(headerName, headerValue); return this; } @Override protected Map getPathParams() { ImmutableMap.Builder params = ImmutableMap.builder(); params.put("identity", identity); return params.build(); } @Override protected String getPathTemplate() { return "refunds/:identity"; } @Override protected String getEnvelope() { return "refunds"; } @Override protected Class getResponseClass() { return Refund.class; } @Override protected boolean hasBody() { return true; } } }