diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java
index 45983b8758a958d2469f7c540963444c1caac650..eb97c1bd57dded333c3185753c10c391b42e39f0 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java
@@ -394,6 +394,7 @@ public class SubscriptionController {
     return switch (paymentMethod) {
       case CARD, SEPA_DEBIT -> stripeManager;
       case PAYPAL -> braintreeManager;
+      case UNKNOWN -> throw new BadRequestException("Invalid payment method");
     };
   }
 
@@ -886,7 +887,7 @@ public class SubscriptionController {
 
       public record Subscription(long level, Instant billingCycleAnchor, Instant endOfCurrentPeriod, boolean active,
                                  boolean cancelAtPeriodEnd, String currency, BigDecimal amount, String status,
-                                 SubscriptionProcessor processor) {
+                                 SubscriptionProcessor processor, PaymentMethod paymentMethod, boolean paymentProcessing) {
 
       }
     }
@@ -919,7 +920,9 @@ public class SubscriptionController {
                             subscriptionInformation.price().currency(),
                             subscriptionInformation.price().amount(),
                             subscriptionInformation.status().getApiValue(),
-                            manager.getProcessor()),
+                            manager.getProcessor(),
+                            subscriptionInformation.paymentMethod(),
+                            subscriptionInformation.paymentProcessing()),
                         subscriptionInformation.chargeFailure()
                     )).build()));
         });
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java
index 1d30c487e1e83676125e49ce6b2c4c82d66f577e..3d039029f28ec1807a1b19d8c976eccb3c7544d6 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/BraintreeManager.java
@@ -426,12 +426,17 @@ public class BraintreeManager implements SubscriptionProcessorManager {
       final Instant anchor = subscription.getFirstBillingDate().toInstant();
       final Instant endOfCurrentPeriod = subscription.getBillingPeriodEndDate().toInstant();
 
-      final ChargeFailure chargeFailure = getLatestTransactionForSubscription(subscription).map(transaction -> {
-        if (getPaymentStatus(transaction.getStatus()).equals(PaymentStatus.SUCCEEDED)) {
-          return null;
+      boolean paymentProcessing = false;
+      ChargeFailure chargeFailure = null;
+
+      final Optional<Transaction> latestTransaction = getLatestTransactionForSubscription(subscription);
+
+      if (latestTransaction.isPresent()){
+        paymentProcessing = isPaymentProcessing(latestTransaction.get().getStatus());
+        if (!getPaymentStatus(latestTransaction.get().getStatus()).equals(PaymentStatus.SUCCEEDED)) {
+          chargeFailure = createChargeFailure(latestTransaction.get());
         }
-        return createChargeFailure(transaction);
-      }).orElse(null);
+      }
 
       return new SubscriptionInformation(
           new SubscriptionPrice(plan.getCurrencyIsoCode().toUpperCase(Locale.ROOT),
@@ -442,11 +447,25 @@ public class BraintreeManager implements SubscriptionProcessorManager {
           Subscription.Status.ACTIVE == subscription.getStatus(),
           !subscription.neverExpires(),
           getSubscriptionStatus(subscription.getStatus()),
+          latestTransaction.map(this::getPaymentMethodFromTransaction).orElse(PaymentMethod.PAYPAL),
+          paymentProcessing,
           chargeFailure
       );
     }, executor);
   }
 
+  private PaymentMethod getPaymentMethodFromTransaction(Transaction transaction) {
+    if (transaction.getPayPalDetails() != null) {
+      return PaymentMethod.PAYPAL;
+    }
+    logger.error("Unexpected payment method from Braintree: {}, transaction id {}", transaction.getPaymentInstrumentType(), transaction.getId());
+    return PaymentMethod.UNKNOWN;
+  }
+
+  private static boolean isPaymentProcessing(final Transaction.Status status) {
+    return status == Transaction.Status.SETTLEMENT_PENDING;
+  }
+
   private ChargeFailure createChargeFailure(Transaction transaction) {
 
     final String code;
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/PaymentMethod.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/PaymentMethod.java
index 4738437eae673b6d5e820d44b4c4adb559afa431..1477e45c3ce73eaf403e8a0201d2e5a92f6c6c37 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/PaymentMethod.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/PaymentMethod.java
@@ -6,6 +6,7 @@
 package org.whispersystems.textsecuregcm.subscriptions;
 
 public enum PaymentMethod {
+  UNKNOWN,
   /**
    * A credit card or debit card, including those from Apple Pay and Google Pay
    */
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java
index c1dc9c6b175bb087acdfa1d78bc7e4a360d3d20d..741df5e4651d88a1508b2f5c82fe38947d3af2d5 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/StripeManager.java
@@ -67,10 +67,12 @@ import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.whispersystems.textsecuregcm.util.Conversions;
 
 public class StripeManager implements SubscriptionProcessorManager {
-
+  private static final Logger logger = LoggerFactory.getLogger(StripeManager.class);
   private static final String METADATA_KEY_LEVEL = "level";
 
   private final StripeClient stripeClient;
@@ -483,17 +485,30 @@ public class StripeManager implements SubscriptionProcessorManager {
     return getPriceForSubscription(subscription).thenCompose(price ->
             getLevelForPrice(price).thenApply(level -> {
               ChargeFailure chargeFailure = null;
-
-              if (subscription.getLatestInvoiceObject() != null && subscription.getLatestInvoiceObject().getChargeObject() != null &&
-                      (subscription.getLatestInvoiceObject().getChargeObject().getFailureCode() != null || subscription.getLatestInvoiceObject().getChargeObject().getFailureMessage() != null)) {
-                Charge charge = subscription.getLatestInvoiceObject().getChargeObject();
-                Charge.Outcome outcome = charge.getOutcome();
-                chargeFailure = new ChargeFailure(
+              boolean paymentProcessing = false;
+              PaymentMethod paymentMethod = null;
+
+              if (subscription.getLatestInvoiceObject() != null) {
+                final Invoice invoice = subscription.getLatestInvoiceObject();
+                paymentProcessing = "open".equals(invoice.getStatus());
+
+                if (invoice.getChargeObject() != null) {
+                  final Charge charge = invoice.getChargeObject();
+                  if (charge.getFailureCode() != null || charge.getFailureMessage() != null) {
+                    Charge.Outcome outcome = charge.getOutcome();
+                    chargeFailure = new ChargeFailure(
                         charge.getFailureCode(),
                         charge.getFailureMessage(),
                         outcome != null ? outcome.getNetworkStatus() : null,
                         outcome != null ? outcome.getReason() : null,
                         outcome != null ? outcome.getType() : null);
+                  }
+
+                  if (charge.getPaymentMethodDetails() != null
+                      && charge.getPaymentMethodDetails().getType() != null) {
+                    paymentMethod = getPaymentMethodFromStripeString(charge.getPaymentMethodDetails().getType(), invoice.getId());
+                  }
+                }
               }
 
               return new SubscriptionInformation(
@@ -504,11 +519,24 @@ public class StripeManager implements SubscriptionProcessorManager {
                   Objects.equals(subscription.getStatus(), "active"),
                   subscription.getCancelAtPeriodEnd(),
                   getSubscriptionStatus(subscription.getStatus()),
+                  paymentMethod,
+                  paymentProcessing,
                   chargeFailure
               );
             }));
   }
 
+  private static PaymentMethod getPaymentMethodFromStripeString(final String paymentMethodString, final String invoiceId) {
+    return switch (paymentMethodString) {
+      case "sepa_debit" -> PaymentMethod.SEPA_DEBIT;
+      case "card" -> PaymentMethod.CARD;
+      default -> {
+        logger.error("Unexpected payment method from Stripe: {}, invoice id: {}", paymentMethodString, invoiceId);
+        yield PaymentMethod.UNKNOWN;
+      }
+    };
+  }
+
   private Subscription getSubscription(Object subscriptionObj) {
     if (!(subscriptionObj instanceof final Subscription subscription)) {
       throw new IllegalArgumentException("invalid subscription object: " + subscriptionObj.getClass().getName());
diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/SubscriptionProcessorManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/SubscriptionProcessorManager.java
index 7be7b2c2d3b87e4ea2700955e46e2b8170e211e4..e82d6e5bc63aa9b72faf593a61c402f42c80fb28 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/SubscriptionProcessorManager.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/subscriptions/SubscriptionProcessorManager.java
@@ -144,8 +144,8 @@ public interface SubscriptionProcessorManager {
 
   record SubscriptionInformation(SubscriptionPrice price, long level, Instant billingCycleAnchor,
                                  Instant endOfCurrentPeriod, boolean active, boolean cancelAtPeriodEnd,
-                                 SubscriptionStatus status,
-                                 ChargeFailure chargeFailure) {
+                                 SubscriptionStatus status, PaymentMethod paymentMethod, boolean paymentProcessing,
+                                 @Nullable ChargeFailure chargeFailure) {
 
   }