diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
index 6aa0bd6..09dda8b 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
@@ -331,11 +331,23 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
}
+ // Is remaining amount > 0 ?
final BigDecimal requestedAmount = validateAndComputePaymentAmount(invoice, paymentControlPluginContext.getAmount(), paymentControlPluginContext.isApiPayment());
+ if (requestedAmount.compareTo(BigDecimal.ZERO) <= 0) {
+ if (paymentControlPluginContext.isApiPayment()) {
+ throw new PaymentControlApiException("Abort purchase call: ", new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION,
+ String.format("Aborted Payment for invoice %s : invoice balance is = %s, requested payment amount is = %s",
+ invoice.getId(),
+ invoice.getBalance(),
+ paymentControlPluginContext.getAmount())));
- final boolean isAborted = requestedAmount.compareTo(BigDecimal.ZERO) == 0;
+ }
+ return new DefaultPriorPaymentControlResult(true);
+ }
- if (!isAborted && paymentControlPluginContext.getPaymentMethodId() == null) {
+
+ // Do we have a paymentMethod ?
+ if (paymentControlPluginContext.getPaymentMethodId() == null) {
log.warn("Payment for invoiceId='{}' was not triggered, accountId='{}' doesn't have a default payment method", getInvoiceId(pluginProperties), paymentControlPluginContext.getAccountId());
invoiceApi.recordPaymentAttemptCompletion(invoiceId,
paymentControlPluginContext.getAmount(),
@@ -349,35 +361,31 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
return new DefaultPriorPaymentControlResult(true);
}
- if (!isAborted && insert_AUTO_PAY_OFF_ifRequired(paymentControlPluginContext, requestedAmount)) {
+
+ // Are we in auto-payoff ?
+ if (insert_AUTO_PAY_OFF_ifRequired(paymentControlPluginContext, requestedAmount)) {
return new DefaultPriorPaymentControlResult(true);
}
- if (paymentControlPluginContext.isApiPayment() && isAborted) {
- throw new PaymentControlApiException("Abort purchase call: ", new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION,
- String.format("Aborted Payment for invoice %s : invoice balance is = %s, requested payment amount is = %s",
- invoice.getId(),
- invoice.getBalance(),
- paymentControlPluginContext.getAmount())));
- } else {
-
- //
- // Insert attempt row with a success = false status to implement a two-phase commit strategy and guard against scenario where payment would go through
- // but onSuccessCall callback never gets called (leaving the place for a double payment if user retries the operation)
- //
- invoiceApi.recordPaymentAttemptInit(invoice.getId(),
- MoreObjects.firstNonNull(paymentControlPluginContext.getAmount(), BigDecimal.ZERO),
- paymentControlPluginContext.getCurrency(),
- paymentControlPluginContext.getCurrency(),
- // Likely to be null, but we don't care as we use the transactionExternalKey
- // to match the operation in the checkForIncompleteInvoicePaymentAndRepair logic below
- paymentControlPluginContext.getPaymentId(),
- paymentControlPluginContext.getTransactionExternalKey(),
- paymentControlPluginContext.getCreatedDate(),
- internalContext);
-
- return new DefaultPriorPaymentControlResult(isAborted, requestedAmount);
- }
+
+ //
+ // Insert attempt row with a success = false status to implement a two-phase commit strategy and guard against scenario where payment would go through
+ // but onSuccessCall callback never gets called (leaving the place for a double payment if user retries the operation)
+ //
+ invoiceApi.recordPaymentAttemptInit(invoice.getId(),
+ MoreObjects.firstNonNull(paymentControlPluginContext.getAmount(), BigDecimal.ZERO),
+ paymentControlPluginContext.getCurrency(),
+ paymentControlPluginContext.getCurrency(),
+ // Likely to be null, but we don't care as we use the transactionExternalKey
+ // to match the operation in the checkForIncompleteInvoicePaymentAndRepair logic below
+ paymentControlPluginContext.getPaymentId(),
+ paymentControlPluginContext.getTransactionExternalKey(),
+ paymentControlPluginContext.getCreatedDate(),
+ internalContext);
+
+ return new DefaultPriorPaymentControlResult(false, requestedAmount);
+
+
} catch (final InvoiceApiException e) {
throw new PaymentControlApiException(e);
} catch (final IllegalArgumentException e) {