diff --git a/self-api/src/main/java/com/selfxdsd/api/Wallet.java b/self-api/src/main/java/com/selfxdsd/api/Wallet.java
index 49304b7c..3492f8c3 100644
--- a/self-api/src/main/java/com/selfxdsd/api/Wallet.java
+++ b/self-api/src/main/java/com/selfxdsd/api/Wallet.java
@@ -63,11 +63,14 @@ default BigDecimal debt() {
* Pay an invoice.
* @param invoice The Invoice to be paid.
* @return Wallet having cash deducted with Invoice amount.
- *
- * @todo #1026:180min Modify method pay(...) to return the Payment created
- * by Invoices.registerAsPai(...).
+ * @todo #1034:90min Write a Wallet decorator which will perform all the
+ * required pre-checks before making a payment (invoice is not paid, the
+ * cash limit is not exceeded etc).
+ * @todo #1034:90min Write a Wallet decorator which will catch any
+ * WalletPaymentException or IllegalStateException thrown from this method
+ * and register a failed Payment for it.
*/
- Wallet pay(final Invoice invoice);
+ Payment pay(final Invoice invoice);
/**
* Type of this wallet.
diff --git a/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java b/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java
index 25d90454..c1fd8573 100644
--- a/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java
+++ b/self-core-impl/src/main/java/com/selfxdsd/core/projects/FakeWallet.java
@@ -108,7 +108,7 @@ public BigDecimal cash() {
}
@Override
- public Wallet pay(final Invoice invoice) {
+ public Payment pay(final Invoice invoice) {
if (!this.project.equals(invoice.contract().project())) {
throw new InvoiceException.NotPartOfProjectContract(invoice,
this.project);
@@ -132,7 +132,7 @@ public Wallet pay(final Invoice invoice) {
+ "..."
);
final String uuid = UUID.randomUUID().toString().replace("-", "");
- this.storage
+ final Payment payment = this.storage
.invoices()
.registerAsPaid(
new StoredInvoice(
@@ -151,7 +151,8 @@ public Wallet pay(final Invoice invoice) {
BigDecimal.valueOf(0),
BigDecimal.valueOf(0)
);
- return this.updateCash(newCash);
+ this.updateCash(newCash);
+ return payment;
}
@Override
diff --git a/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java b/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java
index 1cded7e3..0e515c90 100644
--- a/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java
+++ b/self-core-impl/src/main/java/com/selfxdsd/core/projects/StripeWallet.java
@@ -149,9 +149,11 @@ public BigDecimal cash() {
* @see docs
* @param invoice The Invoice to be paid.
* @return Wallet with the updated cash limit.
+ * @checkstyle CyclomaticComplexity (200 lines)
+ * @checkstyle MethodLength (200 lines)
*/
@Override
- public Wallet pay(final Invoice invoice) {
+ public Payment pay(final Invoice invoice) {
final Contract contract = invoice.contract();
LOG.debug(
"[STRIPE] Trying to pay Invoice #" + invoice.invoiceId() + " of "
@@ -258,7 +260,7 @@ public Wallet pay(final Invoice invoice) {
.ofEpochSecond(paymentIntent.getCreated(),
0, OffsetDateTime.now().getOffset());
final BigDecimal eurToRon = new XmlBnr().euroToRon();
- this.storage.invoices()
+ final Payment payment = this.storage.invoices()
.registerAsPaid(
new StoredInvoice(
invoice.invoiceId(),
@@ -276,6 +278,8 @@ public Wallet pay(final Invoice invoice) {
vat,
eurToRon
);
+ this.updateCash(newLimit);
+ return payment;
} else {
LOG.error("[STRIPE] PaymentIntent status: " + status);
LOG.error("[STRIPE] Cancelling PaymentIntent...");
@@ -287,9 +291,37 @@ public Wallet pay(final Invoice invoice) {
);
}
} catch (final StripeException ex) {
- this.rethrowStripeException(ex, invoice.invoiceId());
+ final int invoiceId = invoice.invoiceId();
+ final String code = ex.getCode();
+ LOG.error(
+ String.format(
+ "[STRIPE] StripeException (code %s, request id %s) "
+ + "while trying to pay Invoice #%s.",
+ code,
+ ex.getRequestId(),
+ invoiceId
+ ),
+ ex
+ );
+ if("authentication_required".equalsIgnoreCase(code)) {
+ throw new WalletPaymentException(
+ "Payment cannot be made because the card "
+ + "requires authentication."
+ );
+ }
+ if("card_declined".equalsIgnoreCase(code)) {
+ final String message = ex.getMessage();
+ throw new WalletPaymentException(
+ "Payment cannot be made: "
+ + message.substring(0, message.indexOf(';'))
+ );
+ }
+ throw new IllegalStateException(
+ "Stripe threw an exception when trying execute PaymentIntent"
+ + " for invoice #" + invoiceId + ": " + ex.getMessage(),
+ ex
+ );
}
- return this.updateCash(newLimit);
}
/**
@@ -466,46 +498,6 @@ public int hashCode() {
return Objects.hash(this.project);
}
- /**
- * Rethrow the StripeException.
- * @param exception StripeException.
- * @param invoiceId Invoice ID.
- */
- private void rethrowStripeException(
- final StripeException exception,
- final int invoiceId
- ) {
- final String code = exception.getCode();
- LOG.error(
- String.format(
- "[STRIPE] StripeException (code %s, request id %s) "
- + "while trying to pay Invoice #%s.",
- code,
- exception.getRequestId(),
- invoiceId
- ),
- exception
- );
- if("authentication_required".equalsIgnoreCase(code)) {
- throw new WalletPaymentException(
- "Payment cannot be made because the card "
- + "requires authentication."
- );
- }
- if("card_declined".equalsIgnoreCase(code)) {
- final String message = exception.getMessage();
- throw new WalletPaymentException(
- "Payment cannot be made: "
- + message.substring(0, message.indexOf(';'))
- );
- }
- throw new IllegalStateException(
- "Stripe threw an exception when trying execute PaymentIntent"
- + " for invoice #" + invoiceId + ": " + exception.getMessage(),
- exception
- );
- }
-
/**
* Calculate the VAT for Self's commission.
*
diff --git a/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java b/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java
index eed3f291..1a12fc26 100644
--- a/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java
+++ b/self-core-impl/src/test/java/com/selfxdsd/core/projects/FakeWalletTestCase.java
@@ -404,7 +404,7 @@ public void canPayInvoice() {
)
).thenReturn(payment);
- final Wallet updated = new FakeWallet(
+ final Payment successful = new FakeWallet(
storage,
project,
BigDecimal.TEN,
@@ -412,8 +412,10 @@ public void canPayInvoice() {
true
).pay(invoice);
- MatcherAssert.assertThat(updated.cash(),
- Matchers.equalTo(BigDecimal.ZERO));
+ MatcherAssert.assertThat(
+ payment,
+ Matchers.is(successful)
+ );
final ArgumentCaptor paidInvoiceCapture = ArgumentCaptor
.forClass(Invoice.class);
diff --git a/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java b/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java
index 253a4225..f38af83d 100644
--- a/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java
+++ b/self-core-impl/src/test/java/com/selfxdsd/core/projects/StripePaymentMethodTestCase.java
@@ -181,7 +181,7 @@ public BigDecimal cash() {
}
@Override
- public Wallet pay(final Invoice invoice) {
+ public Payment pay(final Invoice invoice) {
throw new UnsupportedOperationException();
}