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
11 changes: 7 additions & 4 deletions self-api/src/main/java/com/selfxdsd/api/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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(
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,11 @@ public BigDecimal cash() {
* @see <a href='https://stripe.com/docs/connect/collect-then-transfer-guide'>docs</a>
* @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 "
Expand Down Expand Up @@ -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(),
Expand All @@ -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...");
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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.<br><br>
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,16 +404,18 @@ public void canPayInvoice() {
)
).thenReturn(payment);

final Wallet updated = new FakeWallet(
final Payment successful = new FakeWallet(
storage,
project,
BigDecimal.TEN,
"id",
true
).pay(invoice);

MatcherAssert.assertThat(updated.cash(),
Matchers.equalTo(BigDecimal.ZERO));
MatcherAssert.assertThat(
payment,
Matchers.is(successful)
);

final ArgumentCaptor<Invoice> paidInvoiceCapture = ArgumentCaptor
.forClass(Invoice.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public BigDecimal cash() {
}

@Override
public Wallet pay(final Invoice invoice) {
public Payment pay(final Invoice invoice) {
throw new UnsupportedOperationException();
}

Expand Down