stripe / stripe-java

Java library for the Stripe API.
https://stripe.com
MIT License
806 stars 357 forks source link

Null value from PaymentMethod.retrieve associated to a Link Payment #1863

Closed memovagon closed 3 weeks ago

memovagon commented 3 weeks ago

Describe the bug

Historically we have used the PaymentMethod.retrieve for extracting Card and Billing details. We use PaymentIntents and Stripe Checkout (Payment Element).

Starting the last week, We noticed a high volume of failures in our code caused by a null pointer exemption since paymentMethod object is null. The purchase is accepted and processed ok on Stripe side, but our post process crashes because of this null object. Every single impacted purchase is associated to a Link Purchase.

The payment_methods api call reports a 200 status, but the result is a null object. e.g. GET /v1/payment_methods/pm_1PvsO1BvYZtyWUkoybVSjmJW

This seems to be a posible defect for Link Payments and the associated PaymentMethod object. Let me know if I am missing anything or there is any special consideration for Link Purchases.

I was able to replicate this error on my local, a mac.

We manage to mitigate the problem turning by turning off Link in Dashboard -> Settings -> Payments - Link. This is reenabled everyday around mid night, We have disable this everyday.

To Reproduce

1.- Create a PaymentIntent. 2.- Complete the payment using Checkout and Link. 3.- Try to extract the PaymentMethod associated to the Payment using PaymentMethod.retrieve

Expected behavior

PaymentMethod element is available for PaymentIntents completed using Link.

Code snippets

// pi_3PvsNlBvYZtyWUko1WX1Qjbn
PaymentIntent intent = PaymentIntent.retrieve(paymentIntent);

// pm_1Pvr8XBvYZtyWUkoBGRwUALu
PaymentMethod paymentMethod = PaymentMethod.retrieve(intent.getPaymentMethod());

// paymentMethod is null at this point 
String str = paymentMethod.getCard().getBrand();

Payment Intent

{
  "id": "py_3PvsNlBvYZtyWUko1q9sbdL7",
  "object": "charge",
  "livemode": false,
  "payment_intent": "pi_3PvsNlBvYZtyWUko1WX1Qjbn",
  "status": "succeeded",
  "amount": 2903,
  "amount_captured": 2903,
  "amount_refunded": 0,
  "application": null,
  "application_fee": null,
  "application_fee_amount": null,
  "balance_transaction": "txn_3PvsNlBvYZtyWUko1j0VdnF6",
  "billing_details": {
    "address": {
      "city": "Los Angeles",
      "country": "US",
      "line1": "46309 Warm Springs Boulevard",
      "line2": null,
      "postal_code": "08500",
      "state": "CA"
    },
    "email": "bjackhorseman@wizeline.com",
    "name": "boJack V",
    "phone": "+19055551111"
  },
  "calculated_statement_descriptor": null,
  "captured": true,
  "created": 1725591544,
  "currency": "usd",
  "customer": "cus_QnTKmR6A8Jtx3p",
  "description": null,
  "destination": null,
  "dispute": null,
  "disputed": false,
  "failure_balance_transaction": null,
  "failure_code": null,
  "failure_message": null,
  "fraud_details": {
  },
  "invoice": null,
  "metadata": {
  },
  "on_behalf_of": null,
  "order": null,
  "outcome": {
    "network_status": "approved_by_network",
    "reason": null,
    "risk_level": "normal",
    "risk_score": 14,
    "seller_message": "Payment complete.",
    "type": "authorized"
  },
  "paid": true,
  "payment_method": "pm_1PvsO1BvYZtyWUkoybVSjmJW",
  "payment_method_details": {
    "link": {
      "country": "US"
    },
    "type": "link"
  },
  "radar_options": {
  },
  "receipt_email": null,
  "receipt_number": null,
  "receipt_url": "...",
  "refunded": false,
  "review": null,
  "shipping": null,
  "source": null,
  "source_transfer": null,
  "statement_descriptor": null,
  "statement_descriptor_suffix": null,
  "transfer_data": null,
  "transfer_group": null
}

I used the shell to check a payment_methods for a working(non-link) and not working(link) calls.
I see a bunch of data missing, maybe this is the cause of the defect?

Link Payment 
$ stripe payment_methods retrieve pm_1PvsO1BvYZtyWUkoybVSjmJW 

{
  "id": "pm_1PvsO1BvYZtyWUkoybVSjmJW",
  "object": "payment_method",
  "allow_redisplay": "unspecified",
  "billing_details": {
    "address": {
      "city": "Los Angeles",
      "country": "US",
      "line1": "46309 Warm Springs Boulevard",
      "line2": null,
      "postal_code": "08500",
      "state": "CA",
    },
    "email": "bjackhorseman@wizeline.com",
    "name": "boJack V",
    "phone": "+19055551111",
  },
  "created": 1725591541,
  "customer": "cus_QnTKmR6A8Jtx3p",
  "link": {
    "email": "bjackhorseman@wizeline.com"
  },
  "livemode": false,
  "metadata": {},
  "type": "link"
}

Non-Link Payment
$stripe payment_methods retrieve pm_1PvtXPBvYZtyWUkoVoMyVimm 

{
  "id": "pm_1PvtXPBvYZtyWUkoVoMyVimm",
  "object": "payment_method",
  "allow_redisplay": "unspecified",
  "billing_details": {
    "address": {… 6 items
    },
    "email": null,
    "name": "boJack V",
    "phone": "+19055551111",
  },
  "card": {
    "brand": "visa",
    "checks": {… 3 items
    },
    "country": "US",
    "display_brand": "visa",
    "exp_month": 12,
    "exp_year": 2034,
    "fingerprint": "nsS1uTlQquLvhaQv",
    "funding": "credit",
    "generated_from": null,
    "last4": "1111",
    "networks": {… 2 items
    },
    "three_d_secure_usage": {
      "supported": true,
    },
    "wallet": null,
  },
  "created": 1725595967,
  "customer": "cus_QnUW5KD6w9g5hV",
  "livemode": false,
  "metadata": {},
  "type": "card",
}

OS

linux unix

Java version

Java 8

stripe-java version

v20.3.0

API version

2022-11-15

Additional context

We use stripe-java version 22.3.0

I upgraded to multiple versions until 26.9.0, looking for a resolution, but still the same result. But I was not able to mitigate this problem.

I also tested for more recent API, 2024-06-20 but error persisted.

remi-stripe commented 3 weeks ago

@memovagon Github issues are limited to bugs with the SDK itself and here your question is more an integration support question. I recommend working with developers on our Discord server at https://stripe.com/go/developer-chat or contacting our support team on https://support.stripe.com/contact/email

To unblock you though, I can tell you that the error is likely not coming from what you think. The call to the Retrieve PaymentMethod API likely works since that pm_12345 exists in the API. The issue is with your next line where you seem to assume all PaymentMethods are always for card payments but don't check the type of that PaymentMethod. Stripe supports many payment methods nowadays and some are enabled by default. So you need to make sure that you look at the PaymentMethod object's type property before you try to access information such as getCard() for example which would only work if type is set to card and not link.

If you have follow up questions, make sure to work with our support team: https://support.stripe.com/contact

memovagon commented 3 weeks ago

@remi-stripe thank you for point me into the right direction.